Вы находитесь на странице: 1из 63

UNIVERSIDADE FEDERAL DO RIO DE JANEIRO

INSTITUTO DE MATEMTICA
DEPARTAMENTO DE CINCIA DA COMPUTAO

MATEUS GREGRIO DE SOUZA

PortSP: Uma API para Tcnicas


de Proteo de Software Portveis

Prof. Davidson Rodrigo Boccardo


Orientador
Prof. Luci Pirmez
Co-orientador

Rio de Janeiro, Agosto de 2015

PortSP: Uma API para Tcnicas de Proteo de Software


Portveis
Mateus Gregrio de Souza

Projeto Final de Curso submetido ao Departamento de Cincia da Computao do


Instituto de Matemtica da Universidade Federal do Rio de Janeiro como parte dos
requisitos necessrios para obteno do grau de Bacharel em Cincia da Computao.

Apresentado por:
__________________________________
Mateus Gregrio de Souza
Aprovado por:
__________________________________
Davidson Rodrigo Boccardo, D.Sc.

__________________________________
Luci Pirmez, D.Sc.

__________________________________
Luziane Ferreira de Mendona, D.Sc.

__________________________________
Rafael de Oliveira Costa, M.Sc.

RIO DE JANEIRO, RJ BRASIL


Agosto de 2015

A Deus, sempre, porque dEle e por Ele,


e para Ele, so todas as coisas, a Rafael
e Maria Eutalia, meus amados pais e
amigos, pelo amor e incentivo contnuos
e minha amada noiva Alessandra pela
mo amiga e paciente companhia.

Agradecimentos
Ao meu Deus, toda a gratido, por tudo que a mim fez, faz e far. Pela f renovada a
cada dia e pelo zelo que a mim dispensa em todos os momentos. A sua graa e
misericrdia foram o meu sustento e me fizeram feliz em todo o tempo. Agradeo por
todas as portas que foram abertas, pelas amizades que me proporcionou construir, pelo
conhecimento adquirido e pela primeira etapa de um sonho que se faz realizada.
Aos meus pais, agradeo, por todo amor e carinho com os quais me criaram, e
pelo apoio incondicional que at aqui me possibilitou chegar. Ao longo de toda a minha
vida, vocs foram os maiores motivadores dos meus estudos e me ensinaram a valorizar
cada oportunidade de aprender. Por quantas vezes vocs me incentivaram a seguir em
frente, a sempre dar o melhor de mim, e vibraram junto comigo por cada vitria
alcanada ao longo dessa jornada que a faculdade. Por quantos momentos vocs foram
meu recurso, meus ajudadores. No h dvidas de que sem vocs esse momento no
seria possvel, tanto que, para mim, o diploma de Bacharel em Cincia da Computao
que irei receber tambm deveria incluir o nome de vocs!
minha futura esposa, Alessandra, com quem desejo partilhar todos os dias da
minha vida, eu agradeo por todo o seu imenso amor, carinho, amizade,
companheirismo e pacincia ao longo de todos estes anos que estamos juntos,
principalmente durante o perodo da graduao. Obrigado por compreender as minhas
ausncias durante estes anos de faculdade e por nunca ter desistido de estar ao meu lado.
Voc foi mais do que fundamental para essa conquista e a vitria aqui alcanada
tambm sua!
Agradeo, tambm, a todos os meus familiares e amigos que, certamente, muito
se alegraram pelo meu ingresso na UFRJ e agora vibram comigo por esta etapa
concluda.
ii

Aos meus orientadores, que fizeram com que este trabalho flusse de maneira
natural e no fosse um peso em momento algum. Agradeo pela disponibilidade,
ateno, pacincia e prontido em ajudar.
A todos os meus professores de graduao, agradeo pelo conhecimento
compartilhado, pelo comprometimento acadmico e por cada contribuio para a minha
formao como Cientista da Computao.
Por fim, agradeo a todos que de alguma forma contriburam para que eu
chegasse at aqui e que, sinceramente, torceram por mim e me acompanharam com
cumplicidade. Sem dvidas, este no o fim, mas apenas o incio de uma longa jornada.

iii

RESUMO
PortSP: Uma API para Tcnicas de Proteo de Software Portveis
Mateus Gregrio de Souza
Agosto/2015

Orientador: Davidson Rodrigo Boccardo, D.Sc.


Co-orientador: Luci Pirmez, D.Sc.

Tcnicas de proteo de software, utilizadas para proteger programas contra


ataques Man-At-The-End (MATE), podem ser expressas como uma sequncia de
transformaes de cdigo. A implementao de tais transformaes para cdigo de
baixo nvel produz solues de proteo no portveis, tornando-se necessrio
reimplementar as tcnicas de proteo para cada nova arquitetura que o software for
compilado. Propomos a criao de uma interface de programao que possibilite a
manipulao de cdigo assembly de maneira transparente e portvel, assegurando a
implementao de proteo de software independente da arquitetura.

Palavras-chave: proteo de software, transformaes de cdigo, portabilidade,


assembly.

iv

ABSTRACT
PortSP: An API for Portable Software Protection Techniques
Mateus Gregrio de Souza
August/2015

Advisor: Davidson Rodrigo Boccardo, D.Sc.


Co-advisor: Luci Pirmez, D.Sc.

Software protection techniques, used to protect programs against Man-At-TheEnd attacks (MATE), can be expressed as a sequence of code transformations. The
implementation of such transformations for low-level code produces non-portable
protection solutions, requiring reimplementation for each different architecture that the
software is compiled. We propose the creation of a programming interface that allows
the manipulation of assembly code in a transparent and portable manner, ensuring the
implementation of software protection independent of the architecture.

Keywords: software protection, code transformations, portability, assembly.

Lista de Figuras
Figura 1. Diferena da localizao da maior complexidade entre as arquiteturas RISC e
CISC ................................................................................................................................. 7
Figura 2. Principais diferenas entre as arquiteturas RISC e CISC ................................. 8
Figura 3. Ideia geral e algumas funes da API PortSP ................................................. 11
Figura 4. Processo de uso da API PortSP at a gerao do binrio protegido ............... 12
Figura 5. Benefcio trazido pela API PortSP na implementao de um programa de
proteo de software ...................................................................................................... 13
Figura 6. Estrutura interna de funcionamento da API PortSP ....................................... 14
Figura 7. Esquema apresentando as principais possibilidades de cardinalidade no
mapeamento de instrues virtuais para instrues assembly ....................................... 23
Figura 8. Trecho do arquivo XML contendo o conjunto de registradores disponvel na
arquitetura x86 ............................................................................................................... 30
Figura 9. Trecho do arquivo XML contendo o conjunto de registradores disponvel na
arquitetura ARM ............................................................................................................ 31
Figura 10. Algumas das instrues virtuais definidas pela API PortSP ........................ 32
Figura 11. Mapeamento de algumas instrues virtuais para as instrues assembly da
arquitetura x86 ............................................................................................................... 33
Figura 12. Mapeamento de algumas instrues virtuais para as instrues assembly da
arquitetura ARM ............................................................................................................ 34
vi

Figura 13. Diagrama de classes da API PortSP ............................................................. 36


Figura 14. Funo principal que faz uso das tcnicas de ofuscao de cdigo ............. 39
Figura 15. Implementao da tcnica de ofuscao substituio de instruo utilizando
a API PortSP .................................................................................................................. 40
Figura 16. Implementao da tcnica de ofuscao insero de cdigo esprio
utilizando a API PortSP ................................................................................................. 40
Figura 17. Trechos de cdigo do programa compilado para a arquitetura x86_64 antes
(a) e aps (b) a aplicao das tcnicas de ofuscao ...................................................... 41
Figura 18. Trechos de cdigo do programa compilado para a arquitetura ARMv5TEJ
antes (a) e aps (b) a aplicao das tcnicas de ofuscao ............................................. 42

vii

Lista de Tabelas
Tabela 1. Algumas das operaes definidas que compem a camada de abstrao da API
PortSP............................................................................................................................. 15
Tabela 2. Algumas operaes e a descrio do papel dos elementos que podem
acompanh-las na composio das instrues virtuais. .................................................. 17
Tabela 3. Padres de busca definidos para se referir aos principais tipos de operandos
das linguagens assembly durante a busca por instrues................................................ 26

viii

Lista de Abreviaturas e Siglas


API

Application Programming Interface

ARM

Advanced RISC Machine

CISC

Complex Instruction Set Computer

MATE

Man-At-The-End

RISC

Reduced Instruction Set Computer

XML

EXtensible Markup Language

ix

Sumrio
Agradecimentos

ii

Resumo

iv

Abstract

Lista de Figuras

vi

Lista de Tabelas

viii

Lista de Abreviaturas e Siglas

ix

1 Introduo

1.1. Motivao .................................................................................................... 1


1.2. Objetivos ..................................................................................................... 4
1.3. Trabalhos Relacionados .............................................................................. 4
1.4. Organizao do Texto ................................................................................. 5
2 Conceitos Bsicos

2.1. Arquiteturas de Processadores: CISC vs. RISC .......................................... 6


2.2. Caractersticas das Linguagens Assembly .................................................. 8
3 A API PortSP

10

3.1. Escolhendo o Nvel de Aplicao das Transformaes de Cdigo .......... 10


3.2. Especificao ............................................................................................ 11
x

3.2.1. Viso Geral ............................................................................................ 11


3.2.2. Camada de Abstrao ............................................................................ 15
3.2.2.1. Instrues Virtuais .............................................................................. 15
3.2.2.1.1. Operaes ......................................................................................... 15
3.2.1.1.2. Elementos e Funes de Provisionamento ....................................... 18
3.2.2.2. Mdulos de Informaes Sobre as Arquiteturas ................................. 19
3.2.2.3. Mdulos de Mapeamentos e Validao de Instrues ........................ 20
3.2.3. Funes Bsicas para Transformaes de Cdigo ................................. 24
3.2.3.1. Funo para Encontrar Instrues ....................................................... 25
3.2.3.2. Funo para Inserir Instrues ............................................................ 27
3.2.3.3. Funo para Remover Instrues ........................................................ 27
3.2.3.4. Funo para Substituir Instrues ....................................................... 28
3.2.3.5. Funo para Encontrar Rtulos ........................................................... 29
3.3. Implementao .......................................................................................... 29
4 Experimentos e Anlise de Resultados

38

5 Concluso

44

6 Anexos

45

6.1. Diagrama de Classes completo do prottipo da API PortSP .................... 45


Referncias

47

xi

Captulo 1
Introduo
1.1. Motivao
Ano aps ano, a indstria de software vem sofrendo enormes prejuzos devido a
pirataria de software. Segundo [BSA 2014], 43% do software instalado em
computadores pessoais no mundo inteiro em 2013 no era licenciado, o que representou
um prejuzo de 62,7 bilhes de dlares, correspondente ao valor comercial das
instalaes no licenciadas. O estudo mostra ainda que houve um aumento na
porcentagem de softwares no licenciados instalados em relao ao estudo global
anterior, realizado em 2011.
Alm de prejuzos financeiros para os fabricantes de software, que deixam de
receber o valor comercial das licenas de uso pirateadas, violaes de softwares podem
trazer outros prejuzos ainda mais crticos em alguns casos, no s para os fabricantes de
software como tambm para as organizaes que os utilizam. Um atacante poderia
tentar violar um software com o objetivo de furtar propriedade intelectual algoritmos
que representam vantagem competitiva em relao a empresas concorrentes, design de
implementao do software , furtar dados sensveis contidos no programa chaves
criptogrficas, nmero serial , adulterar o funcionamento do software a fim de obter
vantagens pessoais burlar a verificao de licena de uso ou identificar
vulnerabilidades no software para posteriormente explor-las.
importante observar que o problema de proteo de software difere
consideravelmente de outros problemas tradicionalmente estudados em segurana de
1

computadores. Num cenrio tradicional, o computador de um usurio confivel estaria


sujeito ao ataque de um hacker mal-intencionado (cracker) a partir de outro
computador, ou ao ataque de softwares maliciosos (malwares), como vrus, worms,
cavalos de Tria, hootkits e keyloggers criados pelo cracker. Neste caso, a ideia bsica
para proteger o computador alvo do ataque consiste em adicionar camadas de proteo
ao seu entorno, a fim de impedir o acesso de crackers e malwares ao computador. Alm
disso, so adicionados mecanismos internos de proteo ao computador para detectar a
presena de crackers e malwares e impedir a execuo de aes maliciosas, caso um
cracker ou malware consiga ultrapassar as camadas de proteo externas e acessar o
computador [Collberg e Nagra 2009]. J num cenrio de ataque a software, a principal
caracterstica a de que no existem barreiras que impeam o acesso do atacante ao
software e ao hardware que o contm. Tal caracterstica torna o problema de proteo de
software fundamentalmente mais difcil de ser resolvido em relao a outras ameaas
comumente estudadas em segurana de computadores, pois pesquisadores e
profissionais de proteo de software precisam combater um modelo de ataque
totalmente liberal, no qual necessrio assumir a existncia de um atacante
extremamente poderoso que possui completo acesso ao software e ao hardware que o
contm, com capacidade para inspecion-los, manipul-los e modific-los livremente.
[Akhunzada et al. 2015, Ceccato et.al 2014, Falcarin et. al 2011, Gu et. al 2011].
Ataques desse tipo so denominados ataques Man-At-The-End (MATE)
[Akhunzada et al. 2015]. Num exemplo concreto de ataque MATE, algum malintencionado poderia atacar um medidor de energia eltrica ao submeter o software nele
embarcado a um processo de engenharia reversa, visando num primeiro instante
compreender o seu funcionamento para, em seguida, adulterar o seu cdigo a fim de
fraudar as medies eltricas. Num outro exemplo, com consequncias ainda mais
graves, um ataque MATE a Smart Grids do setor eltrico poderia causar um denial of
service (DoS) na rede eltrica, trazendo srios impactos sobre a infraestrutura nacional
de energia eltrica [Boccardo et al. 2010].
Mtodos de proteo contra ataques MATE so conhecidos como tcnicas antimanipulao, proteo propriedade intelectual ou, mais comumente, tcnicas de
2

proteo de software [Falcarin et al. 2011], que buscam dificultar, adiar ou, no pior dos
casos, minimizar os efeitos de ataques MATE a softwares. Dentre as principais tcnicas
de proteo de software, destacam-se as tcnicas de ofuscao, marca dgua e
incorruptibilidade (ou tamper-proofing) [Collberg e Thomborson 2002]. Tcnicas de
ofuscao de cdigo dificultam a engenharia reversa atravs de modificaes sintticas
que aumentam o grau de ininteligibilidade do cdigo, mas mantm a sua semntica
original. Tcnicas de marca dgua agem como uma defesa contra pirataria de software,
atravs da insero de informaes no cdigo do programa que permitam rastrear sua
autoria ou propriedade. Por fim, tcnicas de incorruptibilidade asseguram que o software
executa como esperado, atravs da adio de cdigo auto verificvel capaz de detectar
tentativas de modificao ou monitorao do software e coibir a continuidade de tais
aes.
Observa-se que as tcnicas de proteo de software consistem em um conjunto
de transformaes aplicadas diretamente sobre o cdigo de um programa, visando
proteg-lo contra ataques de adversrios [Boccardo et al. 2010]. Alm disso,
observamos tambm que as tcnicas de proteo de software se utilizam de uma base
comum de transformaes de cdigo para serem construdas. Por exemplo, em muitas
tcnicas de proteo de software, sejam elas de ofuscao, marca dgua ou
incorruptibilidade, perfeitamente usual a execuo de transformaes como: inserir
novos trechos de cdigo, substituir determinados trechos de cdigo por outros
equivalentes, remover e reordenar trechos de cdigo.
Muitas tcnicas de proteo de software baseiam-se em transformaes de
cdigo aplicadas sobre cdigo de baixo nvel (assembly ou binrio). Porm, o
desenvolvimento de tais tcnicas mostra-se um desafio em relao a portabilidade da
soluo, pois cdigo de baixo nvel , por definio, um cdigo especfico para lidar
com as caractersticas da arquitetura para a qual foi projetado. Logo, as transformaes
de cdigo aplicadas sobre cdigo de baixo nvel e, consequentemente, as tcnicas de
proteo compostas por elas, tornam-se dependentes da arquitetura, obrigando analistas,
desenvolvedores e pesquisadores da rea de segurana a sempre reimplementarem suas
tcnicas de proteo de acordo com a arquitetura para a qual o software a ser protegido
3

foi compilado. Dessa forma, interessante estudar meios para facilitar a implementao
de tcnicas de proteo de software para mltiplas arquiteturas, buscando evitar o
retrabalho de profissionais da rea de segurana de software.

1.2. Objetivos
Este trabalho prope a criao de uma API (Application Programming
Interface), chamada PortSP, que possibilite a implementao de tcnicas e programas de
proteo de software, capazes de serem utilizados para proteger softwares compilados
para mltiplas arquiteturas de hardware. Para tanto, a API proposta fornece um conjunto
de funes bsicas que permitem a execuo de transformaes de cdigo assembly de
mltiplas arquiteturas, bem como facilita a implementao de tcnicas e programas de
proteo de software a partir da simples combinao do uso de tais funes.
A proposta da API PortSP visa atingir dois objetivos principais: prover
portabilidade para as transformaes de cdigo utilizadas na composio de tcnicas de
proteo de software, tornando possvel a implementao de tcnicas de proteo de
software portveis; e, prover funes bsicas que facilitem a implementao de tcnicas
de proteo de software, tanto nos cenrios em que a portabilidade das tcnicas um
requisito, quanto naqueles em que tal portabilidade opcional.

1.3. Trabalhos Relacionados


Encontramos muitas ferramentas comerciais para proteo de software na
internet, dentre elas, diversos ofuscadores de cdigo fonte (escrito em linguagem de alto
nvel) [Semantic Designs, Stunnix, MTC Group, Gapotchenko] e ferramentas de
proteo mais completas que combinam o uso de tcnicas de ofuscao e
incorruptibilidade [GuardSquare] e protegem softwares contra pirataria, manipulao e
engenharia reversa (possivelmente combinando o uso de tcnicas de marca dgua,
incorruptibilidade e ofuscao) [Sciensoft Systems]. Porm, todas elas possuem foco
diferente deste trabalho, pois so ferramentas de cdigo fechado que oferecem mtodos
prontos para proteo de software, enquanto o intento de nossa proposta o de facilitar

a implementao de tcnicas e programas para proteo de software, por analistas,


desenvolvedores e pesquisadores da rea de segurana.
Uma rea de pesquisa que est indiretamente relacionada a este trabalho a rea
de anlise de malware (malicious software). Analistas de malware estudam tcnicas de
ofuscao de cdigo, cdigo auto modificvel, dentre outras tcnicas utilizadas por
desenvolvedores de malwares para camuflar seus programas maliciosos diante de
escaneamentos realizados por programas antivrus. Nesse contexto, [Jain 2012]
apresenta um transformador de cdigo assembly que aplica tcnicas de ofuscao de
cdigo sobre malwares, com o objetivo de criar variantes de malwares no
identificveis por programas antivrus e computar o grau de similaridade entre o
malware original e suas variantes produzidas.
Por fim, [Buck e Hollingsworth 2000] propem uma API para patching de
programas em tempo de execuo, que permite a instrumentao e modificao de
programas durante a sua execuo. Essa API permite a implementao de programas de
instrumentao de binrios independentes de mquina, tendo sido concebida,
primariamente, para facilitar a construo de ferramentas de depurao (debugging) de
cdigo.

1.4. Organizao do Texto


O restante deste trabalho est organizado da seguinte forma: no captulo 2,
introduzimos os conceitos bsicos necessrios para o entendimento deste trabalho; no
captulo 3, apresentamos em detalhes as premissas e abstraes utilizadas no projeto e
implementao da API PortSP; no captulo 4, apresentamos os experimentos realizados
atravs da utilizao de um prottipo da API PortSP e a anlise dos resultados obtidos;
finalmente, no captulo 5, apresentamos as concluses e trabalhos futuros.

Captulo 2
Conceitos Bsicos
Neste captulo esto descritos conceitos bsicos que servem como referncia para a
compreenso deste trabalho. Tratamos aqui sobre algumas diferenas entre as
arquiteturas de processadores CISC e RISC, bem como sobre algumas caractersticas
das linguagens de programao assembly.

2.1. Arquiteturas de Processadores: CISC vs. RISC


Os processadores atuais so implementados de acordo com as especificaes
definidas por modelos de arquitetura de hardware. Dentre estes modelos, destacamos
duas vertentes de arquiteturas utilizadas na implementao de processadores: as
arquiteturas CISC e RISC.
A arquitetura CISC (Complex Instruction Set Computer), define vrias centenas
de instrues complexas diferentes, sendo extremamente verstil. Porm, uma
consequncia de tal versatilidade consiste numa menor velocidade na execuo de
instrues por processadores que implementam esta arquitetura em alguns casos A ideia
principal, que apesar de um processador CISC ser capaz de executar centenas de
instrues diferentes, apenas algumas so usadas frequentemente.
Ao contrrio da complexa arquitetura CISC, a filosofia da arquitetura RISC
(Reduced Instruction Set Computer) consiste na execuo de instrues mais simples,
de reduzida complexidade, porm poderosas, em um ciclo do processador [Sloss et. al
2004]. Os processadores que implementam a arquitetura RISC so capazes de executar
apenas algumas poucas instrues simples. Porm, justamente por isso, os chips
6

baseados nesta arquitetura so mais simples e muito mais baratos. Outra vantagem dos
processadores RISC, que, por terem um menor nmero de circuitos internos, podem
trabalhar a frequncias mais altas, atingindo melhor desempenho que os processadores
CISC na execuo de instrues simples. indiscutvel, porm, que em instrues
complexas os processadores CISC saem-se melhor. Por isso, ao invs da vitria de uma
das duas tecnologias, atualmente vemos processadores hbridos, que so essencialmente
processadores CISC, mas que incorporam muitos recursos encontrados nos
processadores RISC (ou vice-versa) [Morimoto 2007].
A filosofia RISC visa reduzir a complexidade das instrues executadas pelo
hardware. Como resultado, o compilador mais exigido, o que contrasta com a
arquitetura CISC, presente, por exemplo, na famlia de processadores da arquitetura
x86, utilizados nos computadores pessoais. As Figuras 1 e 2 ilustram as principais
diferenas entre as arquiteturas CISC e RISC.

Figura 1. Diferena da localizao da maior complexidade entre as arquiteturas


RISC e CISC.

A complexidade maior ou menor dos processadores ilustrada na Figura 1 refletese diretamente no conjunto de instrues dos processadores de tais arquiteturas. Sendo
assim, neste trabalho projetamos a API PortSP sob a tica de linguagens assembly
utilizadas por processadores que implementam tanto arquiteturas CISC quanto
arquiteturas RISC, de forma a abranger e se adaptar s caractersticas da maior gama
possvel de linguagens assembly.

Figura 2. Principais diferenas entre as arquiteturas RISC e CISC.

2.2. Caractersticas das Linguagens Assembly


A linguagem assembly nada mais do que uma linguagem simblica, utilizada
para representar de maneira mais legvel as instrues de mquina dos processadores de
uma determinada arquitetura. Segundo [Blum 2005], todo programa escrito em
linguagem assembly consiste de trs componentes que so utilizados para definir as
operaes do programa: mnemnicos de cdigos de operao, sees de dados e
diretivas. Infelizmente, diferente de outras linguagens de programao, no existe um
formato padro utilizado por todos os montadores (assemblers) programas que
transformam o cdigo assembly em cdigo de mquina , de forma que cada montador
utiliza formatos ligeiramente distintos para representar cdigos de operao, dados e
diretivas. Chegaram a surgir algumas tendncias com o objetivo de padronizar os
mnemnicos utilizados pelos montadores para se referir aos cdigos de instruo,
porm, o que prevalece at hoje uma ampla variedade de mnemnicos, no somente
entre processadores de famlias distintas, como tambm entre montadores utilizados
para o mesmo conjunto de cdigos de instruo de um processador [Blum 2005].
Alm dos trs componentes utilizados para definir operaes nos programas,
montadores tambm fazem uso de outros elementos para a composio de programas
em linguagem assembly. Por exemplo, comum diversas arquiteturas de hardware o
8

uso de registradores e de pelo menos um segmento de pilha para o armazenamento de


dados. A utilizao de rtulos (labels) para referenciar posies de memria tambm
uma prtica muito utilizada por diversos montadores. O que pode variar de um
montador para outro a sintaxe utilizada para se referir a tais elementos, bem como
caractersticas dos elementos que so inerentes arquitetura do hardware para a qual o
cdigo assembly gerado, como o caso, por exemplo, do conjunto de registradores e
do segmento de pilha, que podem variar em quantidade e tamanho (largura em bits).
Em arquiteturas CISC como a x86, por exemplo, podem existir diferentes
sintaxes de escrita para a linguagem assembly utilizada para um mesmo conjunto de
instrues. A arquitetura x86 define as sintaxes INTEL e AT&T como sintaxes vlidas
para a escrita de cdigo assembly compatvel com essa arquitetura. Observa-se que
programas assembly escritos nessas sintaxes tornam-se bem diferentes na aparncia
(sintaxe), porm mantm-se semanticamente idnticos [Larsen 2007].
Assim, nota-se que existem diferenas entre as linguagens assembly definidas
para as diversas arquiteturas de hardware, porm, a maior parte das linguagens assembly
baseia-se em uma estrutura geral comum, de forma que possvel estabelecer
equivalncias entre as instrues e elementos que compem diferentes linguagens
assembly.

Captulo 3
A API PortSP
Este captulo dedica-se a apresentar em detalhes as premissas e abstraes utilizadas no
projeto e implementao da API PortSP, e est organizado da seguinte forma: a seo
3.1 apresenta uma breve discusso sobre a escolha do nvel de aplicao das
transformaes de cdigo suportado pela API; a seo 3.2 apresenta as abstraes
criadas e demais especificaes da API e, finalmente, a seo 3.3 fornece uma descrio
em alto nvel da implementao de um prottipo da API.

3.1. Escolhendo o Nvel de Aplicao das Transformaes de Cdigo


As transformaes de cdigo podem ser aplicadas tanto em cdigo de alto nvel
(cdigo fonte) quanto em cdigo de baixo nvel (cdigo assembly ou binrio).
Transformaes aplicadas sobre cdigo de alto nvel (cdigo fonte) ocorrem antes do
processo de compilao, visando gerar um binrio mais complexo. Lidar com cdigo de
alto nvel facilita a aplicao das transformaes de cdigo, dada a maior facilidade de
compreenso e escrita em relao a cdigos de nvel mais baixo. Alm disso, os trechos
de cdigo inseridos pelas transformaes passaro pelo processo de otimizao do
compilador, gerando cdigo binrio mais eficiente. J as transformaes de cdigo
aplicadas sobre cdigo de baixo nvel (assembly ou binrio) ocorrem aps o processo de
compilao. necessrio, nesse caso, lidar com cdigo dependente de plataforma e de
compreenso e escrita mais difcil, o que dificulta a aplicao das transformaes. A
vantagem de trabalhar em nvel mais baixo est na possibilidade de aplicao de
transformaes de cdigo mais granulares, a nvel de instrues de mquina. Isso amplia

10

o leque de transformaes de cdigo que podem ser aplicadas sobre o programa, sendo
bastante til, por exemplo, na proteo contra engenharia reversa.
Optamos ento pela aplicao de transformaes sobre cdigo de baixo nvel,
escrito em linguagem assembly, a fim de prover funes que permitam a execuo de
transformaes de cdigo granulares, a nvel de instrues de mquina. A escolha pelo
cdigo assembly foi feita para amenizar parte da dificuldade de compreenso e escrita
de cdigo, que seria ainda maior ao lidar diretamente com cdigo binrio.

3.2. Especificao
3.2.1. Viso Geral
Um dos objetivos da API PortSP o de fornecer ao usurio da API a partir de
agora denominado profissional de segurana ou programador funes que facilitem a
implementao de tcnicas de proteo de software. Para isso, a API prov uma
interface de programao com funes bsicas que facilitam a escrita de transformaes
de cdigo assembly. Funes que permitem encontrar, inserir, remover e substituir
instrues e rtulos, identificar e reordenar blocos bsicos, por exemplo, facilitam a
manipulao do cdigo assembly de tal forma que basta combinar o uso dessas funes
para implementar diversas transformaes de cdigo utilizadas nas tcnicas de
ofuscao, marca dgua e incorruptibilidade de software. O esquema da Figura 3
apresenta a ideia geral de como implementar tcnicas de proteo de software que
podem vir a compor um programa de proteo de software , a partir das funes
bsicas disponibilizadas pela interface de programao da API PortSP.

Figura 3. Ideia geral e algumas funes da API PortSP.

11

A entrada exigida pela API PortSP composta pelo programa alvo das tcnicas
de proteo, escrito em linguagem assembly, e pelo nome da arquitetura para a qual o
programa foi compilado. A API ento capaz de executar sobre o programa alvo da
proteo as tcnicas de proteo de software construdas pelo profissional de segurana,
a partir das funes bsicas providas pela API, aplicando transformaes de cdigo
sobre o programa que produzem instrues assembly escritas na linguagem correta, de
acordo com a informao fornecida na entrada a respeito da arquitetura para a qual o
programa foi compilado. O resultado desse processo uma verso modificada do
programa assembly original, que o profissional de segurana dever utilizar para gerar o
binrio do programa que ser disponibilizado publicamente para download ou aquisio
dos usurios, ou mesmo embarcado em um hardware especfico para comercializao. A
seguir, o esquema da Figura 4 clarifica o processo de uso da API at a gerao do
binrio protegido do programa.

Figura 4. Processo de uso da API PortSP at a gerao do binrio protegido.

Alm disso, o objetivo principal da API PortSP o de prover portabilidade para


tcnicas de proteo de software. Atingir este objetivo significa minimizar o retrabalho
de programadores, analistas e pesquisadores de segurana de software que se veem
obrigados a reimplementar suas tcnicas de proteo de software para cada nova
arquitetura que um programa for compilado. O esquema apresentado na Figura 5 ilustra
12

o benefcio trazido pela API PortSP ao permitir a implementao de um nico programa


de proteo de software capaz de aplicar tcnicas de proteo de software sobre
programas escritos nas linguagens assembly de trs arquiteturas distintas.

(a) Implementao de programas de proteo especficos para cada


arquitetura.

(b) Implementao de um nico programa de proteo genrico utilizando


a API PortSP.
Figura 5. Benefcio trazido pela API PortSP na implementao de um programa
de proteo de software.

13

A fim de atender ao requisito de portabilidade das transformaes de cdigo,


necessrio que as funes bsicas providas pela API PortSP tenham a capacidade de
lidar com cdigos assembly escritos para mltiplas arquiteturas de processadores. Para
tanto, foi projetada uma camada de abstrao que permite lidar com instrues e
elementos da linguagem assembly de mltiplas arquiteturas, de forma transparente e
portvel. Essa camada composta por instrues virtuais, mdulos de informaes
especficas sobre as arquiteturas suportadas pela API, e mdulos de mapeamentos das
instrues virtuais para instrues assembly das arquiteturas suportadas. Assim, ao
implementar transformaes de cdigo utilizando a API PortSP, o profissional de
segurana ir, por exemplo, fazer uso da funo bsica para encontrar uma instruo
parametrizando a busca com uma instruo virtual, e a API se encarregar de traduzir a
instruo virtual utilizada na chamada da funo bsica pela instruo assembly
correspondente na arquitetura do programa alvo das transformaes de cdigo,
utilizando-se para tanto dos mapeamentos de instrues pr-definidos na camada de
abstrao. O esquema apresentado na Figura 6 ilustra de forma simplificada a estrutura
interna de funcionamento da API.

Figura 6. Estrutura interna de funcionamento da API PortSP.

14

As subsees seguintes iro tratar em detalhes sobre a camada de abstrao e as


funes bsicas para transformao de cdigo definidas para a API PortSP.
3.2.2. Camada de Abstrao
3.2.2.1. Instrues Virtuais
As instrues virtuais definidas na camada de abstrao so compostas por
operaes e elementos, sendo cada instruo virtual composta, obrigatoriamente, por
uma operao e, opcionalmente, por um nmero determinado de elementos. As
operaes consistem basicamente em um conjunto de expresses que representam, de
forma genrica, os mnemnicos de operaes utilizados na definio de instrues
assembly de mltiplas arquiteturas. J os elementos representam outros recursos
existentes nas arquiteturas, como registradores, endereos de memria, valores
constantes e rtulos, utilizados pelas linguagens assembly na composio dos
programas. Em geral, os elementos so utilizados em conjunto com as operaes,
fazendo o papel dos operandos de instrues assembly nas instrues virtuais.
3.2.2.1.1. Operaes
Foram definidas operaes para representar os mnemnicos de instrues
assembly comumente utilizadas em tcnicas de proteo de software, considerando
instrues pertencentes aos grupos de instrues de movimentao de dados, instrues
lgicas, instrues aritmticas e instrues de desvio de fluxo. A Tabela 1 apresenta
algumas das operaes definidas acompanhadas de uma breve descrio de cada uma
delas.
Tabela 1. Algumas das operaes definidas que compem a camada de
abstrao da API PortSP.

Operao

Descrio

MOVE

Movimenta dados para um elemento de memria.

PUSH_ONTO_STACK

Coloca um dado na pilha.

15

EXCLUSIVE_OR
AND
SUBTRACT
ADD

RETURN_FROM_FUNCTION

JUMP_IF_ZERO

Ou exclusivo lgico entre dois valores.


E lgico entre dois valores.
Subtrai o segundo valor do primeiro.
Soma dois valores.
Chama uma funo, desviando o fluxo para a
primeira instruo da funo.
Desvia o fluxo para o endereo apontado pelo
operando, se a flag zero est ativada.

Alm disso, para cada uma das operaes foi definido o nmero de elementos
que podem acompanh-las na composio das instrues virtuais, bem como o papel de
cada um desses elementos na operao. As operaes podem ser acompanhadas por
nenhum, um ou dois elementos, semelhantemente ao que ocorre nas instrues assembly
de processadores das arquiteturas RISC e CISC, que so compostas por um mnemnico
de operao, acompanhado de um nmero determinado de operandos com papis e tipos
bem definidos. Ressalta-se, porm, que as instrues virtuais no restringem os tipos de
elementos (registrador, endereo de memria, valor constante ou rtulo) aceitos por
cada operao, uma vez que cada arquitetura define suas prprias limitaes em relao
aos tipos de operandos aceitos pelas instrues assembly. Dessa forma, tais limitaes
so definidas nos mapeamentos das instrues virtuais para as instrues assembly de
cada arquitetura, como ser discutido em detalhes na subseo 3.2.2.3. A Tabela 2
apresenta algumas operaes e uma descrio do papel de cada um dos elementos que
podem acompanh-las na composio das instrues virtuais.

16

Tabela 2. Algumas operaes e a descrio do papel dos elementos que podem


acompanh-las na composio das instrues virtuais.

Instruo Virtual
Operao
MOVE
PUSH_ONTO_STACK

Elemento 1
Operando

de

destino

Elemento 2
da Operando de origem da

operao.

operao.

Dado a ser colocado na pilha.

Operando da esquerda e
EXCLUSIVE_OR

tambm

operando

de Operando da direita da

destino

do

resultado

da operao.

operao.
Operando da esquerda e
AND

tambm

operando

de Operando da direita da

destino

do

resultado

da operao.

operao.
Minuendo da subtrao e
SUBTRACT

tambm

operando

de Subtraendo da operao

destino

do

resultado

da de subtrao.

operao.
Operando da esquerda e
ADD

tambm

operando

de Operando da direita da

destino

do

resultado

da operao.

operao.
RETURN_FROM_FUNCTION
JUMP_IF_ZERO

Endereo

de

desvio de fluxo.

17

destino

do

3.2.1.1.2. Elementos e Funes de Provisionamento


Como dito anteriormente, os elementos representam recursos comuns s diversas
arquiteturas, como registradores, endereos de memria, valores constantes e rtulos.
Uma representao indireta a tais recursos se faz necessria, pois, assim como ocorre
com os mnemnicos de instrues assembly, cada arquitetura define o seu prprio
conjunto de registradores, bem como possui formas especficas para se referir a esses e
outros recursos nas linguagens assembly. Sendo assim, a API PortSP fornece um
conjunto de funes de provisionamento de elementos, a fim de fornecer tais elementos
dinamicamente ao programador, de acordo com os parmetros informados na chamada
dessas funes e com as informaes e regras especficas para cada arquitetura definidas
na camada de abstrao.
No caso de elementos dos tipos registrador e rtulo, no necessrio que o
programador informe qualquer parmetro s funes de provisionamento. Um
registrador provido ao profissional de segurana por uma funo que escolhe um
registrador que no tenha sido fornecido previamente, dentre o conjunto de registradores
de uso geral especificados para a arquitetura. Fazemos a ressalva de que o estado do
registrador fornecido dever ser salvo antes do seu uso e restaurado aps ele, a fim de
evitar que o programa quebre durante a execuo ou tenha a sua semntica alterada. J
um rtulo gerado dinamicamente de acordo com as regras de nomenclatura de rtulos
especificadas para a arquitetura, assegurando que todo rtulo gerado nico no
programa em assembly. Por outro lado, as funes de provisionamento de elementos dos
tipos endereo de memria e constante necessitam receber, respectivamente, os valores
do endereo de memria e da constante que devem ser provisionados. Cabe a API
apenas reescrever tais valores de acordo com as regras de sintaxe definidas para os tipos
de elementos correspondentes na linguagem assembly da arquitetura alvo. Geralmente,
constantes e endereos de memria so identificados na maior parte das linguagens
assembly por prefixos e/ou sufixos adicionados ao valor da constante ou do endereo de
memria.
Em suma, para compor uma instruo virtual, o profissional de segurana dever
utilizar operaes (expresses pr-definidas), para se referir aos mnemnicos das
18

instrues assembly, e elementos que devero ser obtidos dinamicamente a partir das
funes de provisionamento de elementos , para se referir aos recursos disponveis na
arquitetura que sero utilizados como operandos na instruo virtual.
3.2.2.2. Mdulos de Informaes Sobre as Arquiteturas
Para que seja possvel realizar o mapeamento das instrues virtuais para as
instrues assembly, necessrio conhecer as caractersticas de cada arquitetura
suportada API. Mais ainda, para que a API seja capaz de executar automaticamente a
traduo das instrues virtuais para as instrues assembly, necessrio prover meios
para que a API possa consultar as informaes sobre as arquiteturas suportadas, bem
como os mapeamentos das instrues virtuais para as instrues assembly.
Cada arquitetura suportada pela API possui o seu prprio mdulo de
informaes, que tem como papel fundamental concentrar todas as informaes
necessrias para a execuo das funes de provisionamento de elementos. Todas as
informaes sobre os registradores disponveis na arquitetura, bem como informaes
sobre a sintaxe desses e outros recursos na linguagem assembly da arquitetura, devero
ser especificadas neste mdulo.
Todos os registradores disponveis para uso na linguagem assembly da
arquitetura so especificados no mdulo de informaes. Os registradores so
classificados em trs grupos possveis: registradores de uso geral, registradores especiais
e outros registradores, de forma que tal classificao possibilite API lidar de forma
diferenciada com cada grupo de registradores. Por exemplo, registradores de uso geral
so os nicos registradores que devem ser providos ao profissional de segurana pela
funo de provisionamento de registradores. Alm deles, somente os registradores
classificados como especiais, que so o contador de programa (program counter) ou
apontador de instruo, e o apontador de pilha (stack pointer), podem ser provisionados
ao profissional de segurana, sendo estes fornecidos por funes de provisionamento
especficas para esses dois registradores. Tais registradores so comuns a grande maioria
das implementaes de arquiteturas RISC e CISC, sendo, por este motivo, utilizados na
implementao de algumas tcnicas de proteo de software. Esses registradores
19

possuem ainda uma caracterstica diferente em relao aos demais, relacionada a


permisso de acesso/manipulao direta desses registradores por um programa
assembly. Essa informao tambm especificada no mdulo de informaes, pois
utilizada como condicionante para o provisionamento ou no de tais registradores ao
profissional de segurana (o registrador somente provisionado se na arquitetura do
programa alvo da proteo o acesso/manipulao direta do registrador permitido). Por
fim, aqueles classificados como outros registradores correspondem aos demais
registradores existentes na arquitetura que no se enquadram em nenhuma das outras
classificaes. importante que todos os registradores disponveis na arquitetura sejam
especificados, pois, como ser discutido na subseo 3.2.3.1, a funo de encontrar uma
instruo fornecida pela API pode se utilizar de um padro de busca para se referir a
qualquer registrador que esteja sendo utilizado no programa assembly como operando
de uma instruo, sendo necessrio para a realizao de tal busca, uma lista completa de
todos os possveis registradores que podem ser encontrados. Alm das classificaes,
possvel especificar para cada registrador, alm do seu nome, possveis apelidos
(aliases) que a linguagem assembly da arquitetura aceite para se referir a esses recursos.
Para finalizar, no mdulo de informaes tambm so especificadas informaes
a respeito da sintaxe de alguns dos demais recursos disponveis na linguagem assembly
da arquitetura. As informaes esperadas so prefixos e/ou sufixos utilizados na escrita
de endereos de memria e valores constantes. Algumas arquiteturas utilizam prefixos
e/ou sufixos distintos para escrever tais elementos, enquanto outras sequer utilizam
qualquer prefixo e/ou sufixo, sendo esta uma informao importante para que tais
elementos sejam provisionados pela API utilizando a sintaxe correta prevista pela
linguagem assembly da arquitetura.
3.2.2.3. Mdulos de Mapeamentos e Validao de Instrues
Toda instruo virtual ser mapeada pela API PortSP para instrues da
linguagem assembly correspondente arquitetura do programa alvo das tcnicas de
proteo. Inicialmente, a arquitetura para a qual o programa foi compilado dever ser
informada API pelo profissional de segurana, juntamente com o programa que ser
alvo das tcnicas de proteo, de forma que, antes da execuo de qualquer
20

transformao de cdigo sobre o programa, as instrues virtuais utilizadas na


implementao das transformaes sejam traduzidas para as instrues assembly
correspondentes. Essa traduo ser feita de forma automtica pela API, a partir de
mapeamentos pr-definidos de instrues virtuais para instrues assembly de cada
arquitetura suportada pela API.
Um ponto importante a ser observado a cardinalidade do mapeamento entre
instrues virtuais e instrues assembly. Para cada instruo virtual podem existir na
linguagem assembly da arquitetura alvo uma ou vrias instrues assembly
correspondentes, estabelecendo-se uma cardinalidade de 1 para N entre as partes. Isso
ocorre, pois para cada instruo virtual podem existir uma ou mais variantes de
instrues assembly que desempenham o mesmo papel definido para a instruo virtual,
principalmente em linguagens assembly de arquiteturas CISC, onde o conjunto de
instrues mais amplo e complexo. Para cada variante de instruo assembly podem
mudar tanto o mnemnico de operao da instruo quanto o nmero e os tipos dos
operandos, sendo, por este motivo, o mapeamento da instruo virtual feito
individualmente para cada variante de instruo assembly. Nesses casos, tais variantes
so mapeadas em ordem prioritria, de forma que a funo bsica da API para inserir
instruo sempre ir utilizar por padro a primeira variante de instruo assembly
mapeada, enquanto as funes bsicas para encontrar, substituir e remover instruo iro
considerar todas as possveis variantes de instrues assembly na execuo das
transformaes. A subseo 3.2.3 ir discutir com mais detalhes a maneira como os
mapeamentos so utilizados por cada funo bsica provida pela API PortSP.
A raiz do mapeamento da instruo virtual para a(s) instruo(es) assembly a
operao que compe a instruo virtual. A partir da operao, so mapeadas
individualmente todas as possveis variantes de instrues assembly que possuem a
mesma semntica definida para a instruo virtual, sendo cada mapeamento composto
pelo mnemnico da instruo assembly, pela correspondncia entre os elementos da
instruo virtual e os operandos da instruo assembly, os tipos de operandos aceitos
pela instruo assembly e a sintaxe de escrita da instruo assembly, quando esta diferir
da sintaxe padro. Observamos que, para que o mapeamento resulte numa instruo
21

assembly vlida, fundamental que ao mapear os elementos da instruo virtual para os


operandos da instruo assembly sejam respeitados, principalmente, a ordem, a
quantidade e os tipos dos operandos definidos pela linguagem assembly para cada
variante de instruo.
Alm da cardinalidade entre a instruo virtual e todas as possveis variantes de
instrues assembly correspondentes, no mapeamento da instruo virtual para cada
variante de instruo assembly deve ser considerada tambm a cardinalidade da
correspondncia entre os elementos da instruo virtual e os operandos da instruo
assembly. Algumas instrues assembly de arquiteturas RISC e CISC, apesar de
possuirem a mesma semntica, podem apresentar formatos com nmero de operandos
distintos. Um exemplo desse tipo de diferena ocorre com a instruo lgica ou
exclusivo nas arquiteturas x86 (CISC) e ARM (RISC). Na arquitetura x86, a instruo
XOR formada por dois operandos contendo os valores a serem submetidos operao
de ou exclusivo, sendo o primeiro deles, ao mesmo tempo, o operando de destino do
resultado da operao. J na arquitetura ARM, a instruo EOR composta por 3
operandos, sendo o primeiro deles o operando de destino do resultado da operao, e os
outros dois operandos os valores a serem submetidos operao de ou exclusivo. A
Figura 7 mostra um esquema do mapeamento entre instrues virtuais e instrues
assembly, apresentando todas as possibilidades de cardinalidade entre instrues virtuais
e instrues assemlby, e elementos de uma instruo virtual e operandos das instrues
assembly.
Adotamos como formato padro para as instrues virtuais da API PortSP o
formato de operandos mais enxuto, utilizado pelas instrues de arquiteturas CISC,
(como a arquitetura x86), pois esse formato facilita o mapeamento das instrues
virtuais para as instrues assembly tanto de arquiteturas CISC como de arquiteturas
RISC. Nos casos em que o nmero de elementos da instruo virtual menor que o
nmero de operandos da instruo assembly, devido ao fato do operando de destino ser
explcito na instruo assembly, a API simplesmente mapeia o elemento n 1 da
instruo virtual como os operandos n 1 e n 2 da instruo assembly, de forma que o
mesmo elemento far o papel de operando de destino da operao e valor a ser
22

submetido operao. A nica limitao trazida por esta abordagem a de que o


primeiro elemento de todas as operaes lgicas e aritmticas deve ser um elemento de
memria (registrador ou endereo de memria), capaz de armazenar o resultado da
operao.

(a) Cardinalidade

entre

instruo

(b) Cardinalidade

entre

instruo

virtual e variantes de instruo

virtual e variantes de instruo

assembly.

assembly.

(c) Cardinalidade entre elementos da

(d) Cardinalidade entre elementos da

instruo virtual e operandos da

instruo virtual e operandos da

variante de instruo assembly.

variante de instruo assembly.

Figura 7. Esquema apresentando as principais possibilidades de cardinalidade


no mapeamento de instrues virtuais para instrues assembly.

23

Por fim, no momento do mapeamento de uma instruo virtual para uma ou mais
variantes de instruo assembly, a API PortSP deve executar a validao dos elementos
que foram utilizados na composio da instruo virtual, de acordo com os tipos de
operandos aceitos pela variante de instruo assembly mapeada. Os possveis tipos de
operandos so: registradores, rtulos, endereos de memria e constantes. Caso os
elementos utilizados como operandos da instruo virtual no atendam aos requisitos
estabelecidos no mapeamento para a instruo assembly, a API gera uma exceo e as
transformaes de cdigo no so efetivadas sobre o programa. Este processo de
validao importante para que no sejam geradas instrues assembly invlidas, que
venham a impedir a gerao do binrio protegido do programa ou mesmo quebrar o
programa durante a sua execuo.
3.2.3. Funes Bsicas para Transformaes de Cdigo
As funes bsicas para transformaes de cdigo providas pela API PortSP so
a base para a composio de tcnicas de proteo de software portveis. Ademais, alm
de prover meios para a implementao de transformaes de cdigo independentes de
arquitetura, tais funes tambm facilitam a implementao de transformaes de
cdigo para compor tcnicas de proteo de software que, no necessariamente, sero
utilizadas para proteger cdigos assembly compilados para diversas arquiteturas. Sendo
assim, a API PortSP se mostra um ferramental til tanto para os cenrios de proteo de
softwares compilados para mltiplas arquiteturas, quanto para os cenrios de proteo
de softwares compilados para uma nica arquitetura de hardware.
Todas as funes bsicas providas pela API fazem uso, obrigatoriamente, de
instrues virtuais como parmetros. Assim, o profissional de segurana capaz de
implementar as tcnicas de proteo de software sem fazer qualquer referncia a termos
especficos da linguagem assembly de uma determinada arquitetura, de forma que as
tcnicas de proteo implementadas se mantm genricas e podem ser aplicadas sobre
softwares escritos em linuagens assembly de qualquer uma das arquiteturas suportadas
pela API.

24

As subsees a seguir apresentam em detalhes cada uma das funes bsicas


providas pela API PortSP.
3.2.3.1. Funo para Encontrar Instrues
A funo para encontrar uma instruo , em geral, o ponto de partida para a
implementao de qualquer tcnica de proteo de software. O profissional de segurana
deve, primeiramente, encontrar a instruo assembly que ser propriamente o alvo das
transformaes de cdigo ou encontrar uma instruo assembly que identifique uma
posio do cdigo assembly onde as transformaes devem ser aplicadas. Sendo assim,
a funo para encontar uma instruo ir retornar a posio inicial da primeira
ocorrncia da instruo no cdigo do programa assembly, dando ao profissional de
segurana a possibilidade de alterar a instruo assembly encontrada por meio das
funes de remover e substituir instruo ou, simplesmente, utilizar a posio recebida
como ponto de partida para inserir novas instrues assembly ou rtulos. Caso o
profissional de segurana deseje aplicar as mesmas transformaes de cdigo sobre
todas as ocorrncias da instruo assembly encontradas no programa, basta envolver o
cdigo de implementao das transformaes de cdigo em um lao de repetio (for,
while, do-while etc.), de forma que, a cada iterao do lao, seja executada
primeiramente a funo para encontrar a instruo e em seguida as funes relacionadas
a execuo das transformaes de cdigo propriamente ditas.
O nico parmetro esperado pela funo para encontrar instruo a prpria
instruo virtual correspondente instruo assembly que se deseja encontrar. Por
padro, toda instruo virtual deve ser composta por uma operao e nenhum, um ou
dois elementos. Porm, a fim de flexibilizar e aumentar o poder das buscas por
instrues assembly, criamos alguns padres de busca para se referir aos grupos de
elementos que podem ser utilizados na composio de instrues virtuais. O objetivo da
criao dos padres de busca permitir ao profissional de segurana realizar buscas por
instrues assembly que so formadas por um tipo determinado de operando, sem
especificar exatamente qual o operando utilizado. Buscas desse tipo so extremamente
teis na implementao de tcnicas de proteo de software, que atuam sobre instrues
assembly mais especficas. Assim, as instrues virtuais utilizadas como parmetros da
25

funo para encontar instruo podero ser compostas tanto por operaes e elementos
quanto por operaes e padres de busca (no lugar dos elementos). Ao utilizar estes
padres no lugar de elementos explcitos, que seriam obtidos atravs das funes de
provisionamento de elementos, ganhamos flexibilidade na realizao de buscas por
instrues assembly mais especficas, o que, consequentemente, aumenta a capacidade
do profissional de segurana de implementar tcnicas de proteo de software mais
especficas.
A seguir, a Tabela 3 apresenta os padres de buscas criados e uma breve
descrio sobre cada um deles. Ressaltamos mais uma vez que o profissional de
segurana ter sempre total liberdade para compor as instrues virtuais que sero
utilizadas pela funo para encontrar uma instruo, pois o objetivo da API ser sempre
o de prover flexibilidade s implementaes dos profissionais.
Tabela 3. Padres de busca definidos para se referir aos principais tipos de
operandos das linguagens assembly durante a busca por instrues.

Padres de Busca para Operandos


Padro

REG*

MEM*

IMM*

LBL*

OP*

Descrio
Utilizado para se referir a operandos do tipo
registrador.
Utilizado para se referir a operandos do tipo endereo
de memria.
Utilizado para se referir a operandos do tipo valor
imediato (constante).
Utilizado para se referir a operandos do tipo rtulo
(label).
Utilizado para se referir a operandos de qualquer tipo.

26

Por fim, os possveis retornos da funo para encontrar instruo podem ser a
posio inicial da primeira ocorrncia da instruo assembly procurada no cdigo do
programa, caso a instruo assembly seja encontrada, ou, uma posio invlida no
cdigo assembly ou algum outro indicativo de que a instruo assembly no foi
encontrada no cdigo do programa.
3.2.3.2. Funo para Inserir Instrues
A funo para inserir uma instruo adiciona uma instruo assembly no cdigo
do programa numa posio especificada. Os parmetros esperados por essa funo so a
instruo virtual correspondente instruo assembly que se deseja inserir e a posio
no cdigo assembly onde a instruo ser inserida.
Programas escritos em linguagens assembly, em geral, adotam um padro de
formatao de uma nica instruo assembly por linha de cdigo. A API PortSP segue
esse padro, de forma que ao inserir uma instruo assembly no cdigo do programa,
automaticamente adicionado ao final da instruo um caracter de quebra de linha.
Esta funo retorna a primeira posio imediatamente aps a linha que contm a
instruo assembly inserida, ou seja, a primeira posio da prxima linha de cdigo. O
objetivo aqui dar ao profissional de segurana uma continuidade na aplicao das
prximas transformaes de cdigo, que podero partir da posio imediatamente aps a
ltima instruo assembly inserida no cdigo e no mais da posio obtida na busca por
uma instruo assembly. Caso no seja possvel executar a insero da instruo
assembly no cdigo do programa, por qualquer que seja o motivo, a funo retorna uma
posio invlida no cdigo assembly ou algum outro indicativo de que a instruo
assembly no pode ser inserida.
3.2.3.3. Funo para Remover Instrues
A funo para remover uma instruo visa apagar inteiramente uma instruo
assembly presente no cdigo do programa. Dificilmente esta instruo ser utilizada
sozinha, sendo mais comum o seu uso como parte da implementao de uma
transformao de cdigo que visa substituir uma instruo assembly por outras
27

instrues e/ou rtulos. O parmetro esperado por esta funo a posio inicial da
instruo assembly que se deseja remover, geralmente obtida ao executar previamente a
funo para encontrar a instruo. Assumindo que o cdigo assembly do programa
segue o padro de uma nica instruo assembly por linha de cdigo, esta funo
remove inteiramente a linha de cdigo indicada pela posio informada.
De forma a facilitar a remoo de instrues pelo profissional de segurana, foi
definida tambm uma variante desta funo que recebe como parmetro a instruo
virtual correspondente instruo assembly que se deseja remover, ao invs de receber a
posio inicial da instruo. O objetivo evitar que para remover uma instruo
assembly o profissional de segurana tenha que, obrigatoriamente, executar a funo de
busca previamente. Assim, ao receber a instruo virtual como parmetro, a prpria
funo para remover instruo efetua uma busca pela instruo assembly correspondente
e, para a primeira ocorrncia da instruo assembly encontrada, procede com a remoo
da linha de cdigo que contm a instruo. Este recurso, de definir novas funes que
facilitam a execuo de aes que antes eram realizadas de uma forma mais difcil,
chamado de acar sinttico.
Ambas as variantes da funo para remover uma instruo retornam a posio
inicial da instruo assembly removida, que, aps a remoo, passou a indicar a posio
da instruo assembly seguinte instruo que foi removida. Caso no seja possvel
executar a remoo da instruo assembly no cdigo do programa, por qualquer que seja
o motivo, a funo retorna uma posio invlida no cdigo assembly ou algum outro
indicativo de que a instruo assembly no pode ser removida.
3.2.3.4. Funo para Substituir Instrues
A funo para substituir uma instruo outra funo que pode ser vista como
um acar sinttico da interface de programao provida pela API PortSP, visanndo
facilitar a escrita de transformaes de cdigo pelo profissional de segurana. Dizemos
que ela um acar sinttico, pois essa funo nada mais do que uma combinao da
execuo das funes para encontrar uma instruo, remover a instruo encontrada e
inserir no lugar da instruo removida uma nova instruo assembly.
28

Os parmetros esperados por esta funo so a instruo virtual que representa a


instruo assembly que se deseja substituir, e a instruo virtual que representa a nova
instruo assembly a ser inserida no lugar da anterior. J o retorno desta funo pode ser
a primeira posio imediatamente aps a linha que contm a nova instruo assembly
inserida ou, caso no seja possvel executar a substituio da instruo assembly no
cdigo do programa, uma posio invlida no cdigo assembly ou algum outro
indicativo de que a instruo no pode ser substituda.
3.2.3.5. Funo para Encontrar Rtulos
A funo para encontrar um rtulo espera como parmetro o nome do rtulo a
ser encontrado no programa. Ressalta-se que o objetivo desta funo no o de
encontrar ocorrncias onde o rtulo procurado foi utilizado como operando de uma
instruo assembly, mas sim, encontrar a nica ocorrncia no programa onde o rtulo
foi definido. A busca feita pelo rtulo no sensitiva caixa, ou seja, indiferente para
esta funo se o profissional de segurana informouo nome do rtulo em caixa alta ou
caixa baixa. Os possveis retornos dessa funo so a posio inicial da linha que
contm a definio do rtulo ou, caso o rtulo no seja encontrado, uma posio
invlida no cdigo assembly ou algum outro indicativo de que o rtulo no pode ser
encontrado.

3.3. Implementao
Inicialmente, foram implementadas funes base para a execuo de
transformaes de cdigo que permitem a implementao de algumas tcnicas de
ofuscao de software. O prottipo desenvolvido capaz de lidar com cdigos assembly
gerados pelo montador GNU Assembler [Free Software 2014], para as arquiteturas x86
e ARM, utilizando a sintaxe de instrues INTEL.
Parte da camada de abstrao da API foi implementada utilizando arquivos
XML, visando prover extensibilidade s abstraes e facilitar o suporte a novas
arquiteturas. Um nico arquivo XML utilizado para definir as instrues virtuais,
enquanto dois arquivos XML so utilizados para estruturar as informaes de cada
29

arquitetura suportada, sendo um deles para especificar informaes sobre o conjunto de


registradores, regras para nomeao de rtulos, sintaxe de escrita de operandos
imediatos e caractersticas dos demais elementos disponveis na arquitetura, e outro
utilizado para especificar o mapeamento das instrues virtuais para as instrues
assembly da arquitetura.
As Figuras 8 e 9 apresentam trechos dos arquivos XML que representam os
mdulos de informaes das arquiteturas x86 e ARM, respectivamente, conforme a
especificao da API. Nos trechos apresentados, so listados os registradores
disponveis em cada arquitetura. Observamos que os registradores foram classificados
de acordo com os critrios pr-estabelecidos na especificao da API, bem como, no
caso da arquitetura ARM, foram enumerados tambm os apelidos aceitos pela
linguagem assembly para se referir a cada um dos registradores. A separao entre o
nome do registrador e seus possveis apelidos feita pelo caractere | (pipe).

Figura 8. Trecho do arquivo XML contendo o conjunto de registradores


disponvel na arquitetura x86.

30

Figura 9. Trecho do arquivo XML contendo o conjunto de registradores


disponvel na arquitetura ARM.

A Figura 10 apresenta algumas das instrues virtuais definidas na


implementao do prottipo da API. Para cada instruo virtual foi atribuda uma
descrio da operao desempenhada pela instruo virtual, o nmero de elementos que
devem compor a instruo virtual, bem como uma descrio do papel de cada um dos
elementos.
As Figuras 11 e 12 apresentam o mapeamento de trs instrues virtuais para as
instrues assembly correspondentes nas arquiteturas x86 e ARM, respectivamente. Os
mapeamentos apresentados ilustram alguns dos possveis casos de cardinalidade entre
instruo virtual e instrues assembly, e elementos de uma instruo virtual e
operandos de uma variante de instruo assembly, alm de ilustrarem tambm a
delimitao dos tipos de operandos aceitos por cada variante de instruo assembly,
conforme discutido previamente na subseo 3.2.2.3.

31

Figura 10. Algumas das instrues virtuais definidas pela API PortSP.

32

Figura 11. Mapeamento de algumas instrues virtuais para as instrues


assembly da arquitetura x86.

Os tipos dos operandos T_REGISTER, T_MEMORY e T_IMMEDIATE foram


definidos para representar, respectivamente, os tipos de recurso registrador, endereo de
memria e constante (ou operando imediato), a fim de delimitar os possveis tipos de
operandos aceitos por cada variante de instruo assembly.
O mapeamento entre elementos das instrues virtuais e operandos das
instrues assembly definido por meio da tag XML <operandX>, onde X representa o
nmero do operando da instruo assembly, e de seu atributo element. Essa forma de
implementao facilita e simplifica bastante o mapeamento entre as partes.

33

Figura 12. Mapeamento de algumas instrues virtuais para as instrues


assembly da arquitetura ARM.

Ao comprar os mapeamentos realizados para as duas arquiteturas, nota-se as


peculiaridades de cada uma delas. O formato adotado para as instrues virtuais
bastante parecido com o formato das instrues assembly da arquitetura x86, de forma
que o mapeamento para as instrues assembly dessa arquitetura foi um pouco mais
simples e direto, havendo, por exemplo, correspondncia exata entre o nmero de
elementos das instrues virtuais e os operandos das instrues assembly mapeadas. J
ao avaliarmos os mapeamentos para as instrues assembly da arquitetura ARM,
observamos a ocorrncia de diversas peculiaridades previstas na especificao da API.
34

Por exemplo, no mapeamento da instruo RETURN_FROM_PROCEDURE, so


mapeadas duas variantes de instruo assembly com a mesma semntica definida pela
instruo virtual. Alm disso, observa-se que a instruo virtual no possui nenhum
elemento, porm, ambas as variantes da instruo assembly possuem operandos fixos
que devem ser explcitos nos mapeamentos. Por este motivo, os operandos de ambas as
variantes foram escritos explicitamente, no lugar dos tipos de operandos, e foi atribudo
ao atributo element de cada operando o valor none, que quer dizer nenhuma
correspondncia. No mapeamento das instrues virtuais EXCLUSIVE_OR e ADD,
observamos que tambm existe diferena entre o nmero de elementos das instrues
virtuais e o nmero de operandos das instrues assembly, conforme previsto na
especificao da API e discutido na subseo 3.2.2.3. A existncia de um operando a
mais nas instrues assembly da arquitetura ARM para armazenar o resultado da
operao suprida de maneira simples pelo mapeamento, bastando mapear os
operandos 1 e 2 da instruo assembly para o elemento 1 da instruo virtual que faz
os papis de operando esquerdo da operao e destino do resultado da operao.
Por fim, as interfaces de programao foram implementadas utilizando a
linguagem de programao C++, com o intuito de, futuramente, disponibilizar a API
PortSP como uma biblioteca dessa linguagem. A Figura 13 apresenta um diagrama
resumido das classes que compem a API. Uma verso completa deste diagrama est
disponvel no Anexo 6.1 deste trabalho.
A seguir, apresentada uma breve descrio das principais classes que compem
a API PortSP.
AssemblyManipulator a classe principal da API e a nica que deve ser
utilizada diretamente pelo programador. Essa classe concentra todas as funes que o
programador necessita para implementar as transformaes de cdigo utilizadas em suas
tcnicas de proteo. No prottipo implementado, essa classe contm as funes para
encontrar, inserir, remover e substituir instrues e rtulos, alm das funes para
prover registradores e rtulos dinamicamente. Todas essas funes acionam mtodos
das classes a seguir para prover tais funcionalidades, fazendo da classe
AssemblyManipulator apenas uma fachada.
35

Figura 13. Diagrama de classes da API PortSP.

VirtualInstructionMapper a classe responsvel por fazer o mapeamento das


instrues virtuais utilizadas pelo programador para a(s) instruo(es) assembly
correspondente(s) de acordo com a arquitetura do programa a ser modificado. Essa
classe utiliza o arquivo XML com os mapeamentos das operaes para as instrues
assembly a fim de compor a instruo assembly final, que dever ser formada
obrigatoriamente por um mnemnico, opcionalmente por operandos, e estar escrita na
sintaxe correta, de acordo com as especificaes da arquitetura alvo.
ResourceManager a classe responsvel pelo provimento dos elementos
utilizados na composio das instrues virtuais, como registradores, endereos de
memria, constantes e rtulos. Para tanto, esta classe possui acesso ao mdulo de
informaes sobre a arquitetura, que contm a listagem do conjunto de registradores de
uso geral disponveis na arquitetura, bem como as especificaes sobre a sintaxe dos
elementos.
AssemblyCodeEditor a classe que efetivamente aplica as transformaes de
cdigo sobre o arquivo assembly. As funes dessa classe recebem as instrues
assembly em seu formato final (aps o mapeamento) e executam as transformaes de
cdigo acionadas. Esta classe mantm todo o cdigo assembly do programa alvo da
proteo em memria, de forma que todas as transformaes de cdigo so executadas
em memria, evitando-se assim latncia em disco devido a operaes de I/O, caso as
36

transformaes fossem executadas diretamente no arquivo em disco. Para que a nova


verso do programa assembly seja gravada em disco, necessrio realizar uma chama a
funo save() da API.

37

Captulo 4
Experimentos e Anlise de Resultados
A fim de avaliar o prottipo criado, realizamos um experimento que consiste em
compilar um mesmo software para duas arquiteturas distintas, utilizar um programa de
proteo implementado a partir da API PortSP para aplicar tcnicas de ofuscao de
cdigo sobre ambas as verses compiladas do software, gerar os binrios
correspondentes para cada arquitetura a partir dos programas ofuscados e, por fim,
execut-los, a fim de verificar se nenhuma das instrues inseridas quebrou o programa
ou alterou a sua semntica.
O programa de proteo implementado aplica conjuntamente duas tcnicas de
ofuscao de cdigo apresentadas por [Branco 2012]. A primeira tcnica, chamada de
Substituio de Instruo, consiste em trocar uma instruo assembly (ou um conjunto
delas) por outras semanticamente equivalentes. J a segunda, denominada Insero de
Cdigo Esprio, consiste em inserir instrues que nunca sero executadas pelo
programa. As Figuras 14, 15 e 16 apresentam os cdigos de implementao do
programa de proteo utilizando a API PortSP.
Como alvo do programa de proteo, implementamos um software gerador de
matrizes e o compilamos para as arquiteturas x86 de 64 bits (x86_64) e ARM de 32 bits
(ARMv5TEJ) [ARM 2005], gerando, respectivamente, os programas matriz_x86.s e
matriz_arm.s escritos nas linguagens assembly das arquiteturas correspondentes.
Executamos o programa de proteo duas vezes, sendo cada execuo com a finalidade
de proteger um dos programas assembly gerados. A cada execuo, foram informados
dois parmetros de entrada: o programa p alvo da proteo (escrito em assembly) e a
38

arquitetura a para a qual o programa p foi compilado. Na primeira execuo, os


parmetros informados foram p = matriz_x86.s e a = x86_64. J na segunda execuo,
os parmetros informados foram p = matriz_arm.s e a = ARMv5TEJ.
Entrada: Programa p escrito em assembly, Arquitetura a para a qual p foi compilado.
Sada: Programa p modificado aps aplicao das tcnicas de ofuscao.
1 int main( int argc, char* argv[] ) {
2

if( argc != 3 ) {

printf( Nmero de argumentos invlido! );

return -1;

} else {

p = argv[1];

a = argv[2];

AssemblyManipulator am = new AssemblyManipulator( p, a );

10 fakeCodeInsertion( am, JUMP );


11 instructionSubstitution( am, JUMP );
12 return 0;
13 }
Figura 14. Funo principal que faz uso das tcnicas de ofuscao de cdigo.

1 void instructionSubstitution( AssemblyManipulator& am, string instruction ) {


2

size_t pos = am.find_instruction( instruction );

while( pos ) {

am.remove_instruction( pos );

string reg_xor = am.giveMeARegister();

am.insert_instruction( EXCLUSIVE_OR, reg_xor, reg_xor );

string rotulo = am.giveMeALabel();

39

am.insert_instruction( JUMP_IF_ZERO, rotulo );

am.insert_label( rotulo );

10

pos = am.find_instruction( instruction );

11 }
12 }
Figura 15. Implementao da tcnica de ofuscao substituio de instruo
utilizando a API PortSP.

1 void fakeCodeInsertion( AssemblyManipulator& am, string instruction_after_fake_code ) {


2

size_t pos = am.find_instruction(instruction_after_fake_code);

while( pos ) {

string reg_xor = am.giveMeARegister();

string reg_mov = am.giveMeARegister();

string rotulo_destino = am.giveMeALabel();

string rotulo_fake = am.giveMeALabel();

string immediate = am.giveMeAnImmediate( 40 );

am.insert_instruction( EXCLUSIVE_OR, reg_xor, reg_xor );

10

am.insert_instruction( JUMP_IF_NOT_ZERO, rotulo_fake );

11

am.insert_instruction( JUMP, rotulo_destino );

12

am.insert_label( rotulo_fake );

13

am.insert_instruction( ADD, reg_xor, immediate );

14

am.insert_instruction( MOVE, reg_mov, reg_xor );

15

am.insert_instruction( RETURN_FROM_FUNCTION );

16

am.insert_label( rotulo_destino );

17

pos = am.find_instruction( instruction_after_fake_code );

18 }
19 }
Figura 16. Implementao da tcnica de ofuscao insero de cdigo
esprio utilizando a API PortSP.

40

As Figuras 17 e 18 apresentam a comparao entre trechos de cdigo dos


programas compilados para as arquiteturas x86_64 e ARMv5TEJ, antes e aps a
aplicao das tcnicas de ofuscao de cdigo, respectivamente. Destacamos em negrito
os trechos de cdigo assembly que foram alterados pelo programa de proteo.
1

mov esi, eax

mov esi, eax

mov edi, OFFSET FLAT:.LC1

mov edi, OFFSET FLAT:.LC1

mov eax, 0

mov eax, 0

call printf

call printf

mov edi, 0

mov edi, 0

call time

call time

mov edi, eax

mov edi, eax

call srand

call srand

mov DWORD PTR [rbp-8], 0

mov DWORD PTR [rbp-8], 0

10 jmp .L2

10 xor ecx, ecx


11 jnz LBL2
12 jmp LBL1
13 LBL2:
14 add ecx, 40
15 mov eax, ecx
16 ret
17 LBL1:
18 xor ebx, ebx
19 jz .L2
(a)

(b)

Figura 17. Trechos de cdigo do programa compilado para a arquitetura x86_64


antes (a) e aps (b) a aplicao das tcnicas de ofuscao.

41

mov r0, r2

mov r0, r2

mov r1, r3

mov r1, r3

bl printf

bl printf

mov r0, #0

mov r0, #0

bl time

bl time

mov r3, r0

mov r3, r0

mov r0, r3

mov r0, r3

bl srand

bl srand

mov r3, #0

mov r3, #0

10 str r3, [fp, #-16]

10 str r3, [fp, #-16]

11 b

11 eors r1, r1, r1

.L2

12 bne LBL2
13 b

LBL1

14 LBL2:
15 adds r1, r1, #40
16 movs r7, r1
17 movs pc, lr
18 LBL1:
19 eors r3, r3
20 beq .L2
(a)

(b)

Figura 18. Trechos de cdigo do programa compilado para a arquitetura


ARMv5TEJ antes (a) e aps (b) a aplicao das tcnicas de ofuscao.

Para finalizar o experimento, geramos os binrios a partir das verses ofuscadas


dos programas e observamos que ambos os binrios executaram normalmente,
apresentando a mesma semntica do programa original.
Observamos atravs deste experimento que a implementao das tcnicas de
ofuscao de cdigo propostas e a sua aplicao sobre softwares compilados para
plataformas distintas foi bastante facilitada pela API PortSP. Atravs de poucas linhas
42

de cdigo (um total de apenas 44 linhas) foi possvel implementar um programa de


proteo de software que aplica duas tcnicas de ofuscao de cdigo sobre programas
de mltiplas plataformas. Alm disso, aplicar tais tcnicas de proteo sobre softwares
compilados para plataformas distintas no exigiu a reescrita de nenhuma linha de cdigo
sequer do programa de proteo, bastando ao profissional de segurana apenas executlo duas vezes, informado a cada execuo o software a ser protegido e a arquitetura
correspondente. Por fim, verificamos tambm que a aplicao em conjunto das tcnicas
de insero de cdigo esprio e substituio de instruo foi um bom estudo de caso
para a validao da API PortSP, uma vez que a implementao dessas tcnicas fez uso
das principais funes providas pela API e a aplicao de tais tcnicas sobre ambas as
verses do software gerador de matrizes proporcionou um nvel de proteo aceitvel ao
aumentar a complexidade ao cdigo assembly final, o que certamente dificultaria a
anlise deste por um atacante durante um processo de engenharia reversa.

43

Captulo 5
Concluso
Neste trabalho, apresentamos o projeto da API PortSP para facilitar a implementao de
tcnicas de proteo de software em contextos de mltiplas arquiteturas. Os resultados
obtidos por meio da utilizao de um prottipo da API foram considerados satisfatrios,
uma vez que foi possvel, com poucas linhas de cdigo, implementar tcnicas de
proteo para proteger softwares compilados para mltiplas arquiteturas e, de forma
extremamente simples, aplic-las sobre verses de um software compiladas para
arquiteturas distintas. Em trabalhos futuros, pretendemos evoluir o prottipo a fim de
oferecer suporte arquitetura AVR, alm de implementar novas funes bsicas que
possibilitem a implementao de tcnicas de marca dgua e incorruptibilidade.

44

Captulo 6
Anexos
6.1. Diagrama de Classes completo do prottipo da API PortSP
Vide imagem na prxima pgina.

45

46

Referncias
Akhunzada, A., Sookhak, M., Anuar, N., Gani, A., Ahmed, E., Shiraz, M., Furnell, S.,
Hayat, A. and Khan, M. (2015). Man-At-The-End Attacks: Analysis, Taxonomy,
Human Aspects, Motivation and Future Directions, Journal of Network and
Computer Applications, vol. 48, p. 44-57.
ARM LTD (2005). ARM Architecture Reference Manual (ARM DDI 0100I),
https://silver.arm.com/download/ARM_Architecture/AR550-DA-70002-r0p000rel0/DDI%2001001.pdf. Acesso em Julho de 2015.
Blum, Richard (2005), Professional Assembly Language, Wrox, 1st edition.
Boccardo, D. R., Machado, R. C. S., Carmo, L. F. R. C. (2010). Transformaes de
cdigo para proteo de software, X Simpsio Brasileiro em Segurana da
Informao e de Sistemas Computacionais, Minicursos, cap. 3, p. 103-148.
Branco, R. R., Barbosa, G. N., Neto, P. D. (2012). Scientific but Not Academical
Overview

of

Malware

Anti-Debugging,

Anti-Disassembly

and

Anti-VM

Technologies, Black Hat USA.


Buck, B., Hollingsworth, J. K. (2000). An API for Runtime Code Patching,
International Journal of High Performance Computing Applications, vol. 14(4), p.
317-329.
BSA, Software Alliance (2014). BSA Global Software Survey: The Compliance Gap,
http://globalstudy.bsa.org/2013/downloads/studies/2013GlobalSurvey_Study_en.pdf.
Acesso em Julho de 2015.
Ceccato M., Di Penta M., Falcarin P., Ricca F., Torchiano M., Tonella P. (2014). A
family of experiments to assess the effectiveness and efficiency of source code
obfuscation techniques, Empirical Software Engineering, vol. 19, p. 1040-1074.
47

Collberg, C. and Nagra, J. (2009). Surreptitious Software: Obfuscation, Watermarking,


and Tamperproofing for Software Protection, Addison-Wesley, 1st edition.
Collberg, C. and Thomborson, C. (2002). Watermarking, Tamper-Proofing, and
Obfuscation Tools for Software Protection, IEEE Transactions on Software
Engineering, vol. 28, no. 8, p. 735-746.
Falcarin, P., Collberg, C., Atallah, M., Jakubowski, M. (2011). Software Protection,
Guest Editors' Introduction, IEEE Software, vol. 28(2), p. 24-27.
Free Software Foundation, Inc. (2014). Using as The GNU Assembler, version 2.25,
https://www.sourceware.org/binutils/docs-2.25/as/index.html. Acesso em Julho de
2015.
Gapotchenko

(2015).

Eazfuscator.NET

Version

4.9,

http://www.gapotchenko.com/eazfuscator.net. Acesso em Julho de 2015.


Gu, Y. X., Wyseur B., Preneel B. (2011). Software-Based Protection Is Moving to the
Mainstream, IEEE Software, vol. 28.
GuardSquare NV (2015). DexGuard, https://www.guardsquare.com/dexguard, Julho.
Morimoto, Carlos E. (2007). Processadores RISC X Processadores CISC,
http://www.hardware.com.br/artigos/risc-cisc/. Acesso em Julho de 2015.
Jain, S. (2012). Malware Obfuscator for Malicious Executables, Global Trends in
Information Systems and Software Applications: 4th International Conference,
ObCom 2011, Part II, p. 461-469.
Larsen, Kim Skak (2007). CSCI 223 Computer Organisation and Assembly Language,
http://www.imada.sdu.dk/Courses/DM18/Litteratur/IntelnATT.htm. Acesso em Julho
de 2015.
MTC Group LTD (2012). Morpher 2.0, http://morpher.com. Acesso em Julho de
2015.
Sciensoft

Systems

(2015).

ElecKey

http://www.sciensoft.com/products/eleckey. Acesso em Julho de 2015.


48

2.0.8.30,

Semantic Designs, Inc. (2015). Thicket Family of Source Code Obfuscators,


http://www.semdesigns.com/Products/Obfuscators/index.html. Acesso em Julho de
2015.
Stunnix (2015). C++ Obfuscator, http://stunnix.com. Acesso em Julho de 2015.
Sloss, A., Symes, D., Wright, C. (2004). ARM

System

Developer's

Guide:

Designing and Optimizing System Software (The Morgan Kaufmann Series in


Computer Architecture and Design). Morgan Kaufmann. ISBN: 9780080490496.

49

Вам также может понравиться