Afschermen van Bibliotheekinterfaces in Windows tegen Aanvallen

Maat: px
Weergave met pagina beginnen:

Download "Afschermen van Bibliotheekinterfaces in Windows tegen Aanvallen"

Transcriptie

1 Afschermen van Bibliotheekinterfaces in Windows tegen Aanvallen Bert Abrath Promotor: prof. dr. ir. Bjorn De Sutter Begeleiders: ir. Stijn Volckaert, dr. Jonas Maebe, dr. Bart Coppens Masterproef ingediend tot het behalen van de academische graad van Master of Science in de ingenieurswetenschappen: computerwetenschappen Vakgroep Elektronica en Informatiesystemen Voorzitter: prof. dr. ir. Jan Van Campenhout Faculteit Ingenieurswetenschappen en Architectuur Academiejaar

2 Voorwoord In de eerste plaats wil ik mijn promotor, prof. dr. ir. Bjorn De Sutter, bedanken voor zijn ondersteuning en uitstekende feedback op deze scriptie. Ook wil ik mijn begeleiders, ir. Stijn Volckaert, dr. Bart Coppens en dr. Jonas Maebe, bedanken voor de hulp en inzicht die ze mij hebben geboden. Specifiek bedank ik Stijn voor het delen van zijn kennis over de interne werking van Windows, en Bart en Jonas voor de hulp die zij geboden hebben toen ik worstelde met problemen in Diablo. Naast mijn promotor en begeleiders zijn er nog twee mensen die op een directe wijze een invloed hebben gehad op deze scriptie door ze uit vrije wil na te lezen: Ronald en mijn zus, Margo. Op indirecte wijze hebben er natuurlijk veel meer mensen bijgedragen aan deze scriptie. Zo was er altijd een stimulerende werkomgeving met een goede sfeer en interessante verhalen beschikbaar. Het afgelopen academiejaar heb ik dan ook veel bijgeleerd over AllyDBG, XOR linked lists, GoT, en the A-Team, en heb ik een gezonde paranoia ten opzichte van willekeurige toetsaanslagen aangeleerd. Hiervoor dank ik Bart, Ronald, Stijn, Jens, Jonas en Sander. Graag wil ik ook de mensen van de Werkgroep Ethical Hacking (van wie ik velen reeds vernoemd heb) bedanken voor het aanwakkeren van mijn interesse in beveiliging. Een goede leefomgeving was natuurlijk ook belangrijk. Daarvoor dank ik mijn ouders, mijn zussen, en mijn bijna 1-jarige neefje, Mathiz, dat altijd een interessante afleiding vormde en er in zijn talloze pogingen nooit is in geslaagd mijn laptop, boeken of papieren, schade aan te doen. Ook in Gent kon ik mij altijd thuis voelen. Ik wil mijn ganggenoten op kot danken voor de vele jaren aan plezier. De gezelschapsspelletjes, andere spelletjes, zang- en danssessies, kooksessies en veel meer zullen mij nog lang bijblijven. Naast mijn vele vrienden op kot wil ik ook mijn andere vrienden doorheen de jaren bedanken voor de vele onvergetelijke verhalen en het algemeen jolijt. Bert Abrath 10 juni 2014 II

3 Toelating tot bruikleen De auteur geeft de toelating deze scriptie voor consultatie beschikbaar te stellen en delen van de scriptie te kopiëren voor persoonlijk gebruik. Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzonder met betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het aanhalen van resultaten uit deze scriptie. The author gives permission to make this master dissertation available for consultation and to copy parts of this master dissertation for personal use. In the case of any other use, the limitations of the copyright have to be respected, in particular with regard to the obligation to state expressly the source when quoting results from this master dissertation. Bert Abrath 10 juni 2014 III

4 Afschermen van Bibliotheekinterfaces in Windows tegen Aanvallen door Bert Abrath Promotor: prof. dr. ir. Bjorn De Sutter Begeleiders: ir. Stijn Volckaert, dr. Jonas Maebe, dr. Bart Coppens Masterproef ingediend tot het behalen van de academische graad van Master of Science in de ingenieurswetenschappen: computerwetenschappen Vakgroep Elektronica en Informatiesystemen Voorzitter: prof. dr. ir. Jan Van Campenhout Faculteit Ingenieurswetenschappen en Architectuur Academiejaar Samenvatting Een dynamisch gelinkte applicatie bestaat uit een uitvoerbaar bestand en een aantal dynamische bibliotheken (die ook door andere applicaties gebruikt kunnen worden). Dynamisch gelinkte applicaties hebben echter een beveiligingsprobleem: de interfaces tussen de verschillende componenten zijn perfecte aanknopingspunten voor reverse engineering. Om reverse engineering tegen te gaan willen we het gebruik van deze interfaces afschermen. Het gebruik van bibliotheekinterfaces door het uitvoerbaar bestand wordt in een eerste methode verborgen d.m.v. van encryptie. In een tweede methode wordt de applicatie volledig statisch gelinkt, door alle gebruikte delen uit de dynamische bibliotheken toe te voegen aan het uitvoerbaar bestand. Volledig statisch gelinkte applicaties zijn echter niet compatibel met meerdere versies van Windows omdat de interface die de Windows-kernel aanbiedt niet stabiel is. Daarom werd er in de tweede methode voor gezorgd dat deze statisch gelinkte applicaties zichzelf kunnen aanpassen aan de versie van Windows waarop ze uitgevoerd worden. Beide methodes zijn als proof-of-concept geïmplementeerd en kunnen nog niet gebruikt worden om realistische applicaties te herschrijven. Ze werden geïmplementeerd op Diablo, een raamwerk ontwikkeld binnen CSL om applicaties te herschrijven. Trefwoorden: Beveiliging, bibliotheekinterfaces, reverse engineering, Windows, Diablo IV

5 Protecting Library Interfaces in Windows against Attacks Bert Abrath Supervisor(s): prof. dr. ir. Bjorn De Sutter, ir. Stijn Volckaert, dr. Jonas Maebe, dr. Bart Coppens Abstract Dynamically linked applications consist of an executable, and a number of dynamic libraries that can be used by other executables. The benefits of this approach to creating applications notwithstanding, the interfaces between these components make the application more susceptible to reverse engineering. Consequently, from a security perspective it is preferable to build statically linked applications. Fully statically linked applications however are not compatible with multiple versions of Windows. In this dissertation two methods are presented that protect the use of library interfaces from reverse engineering. These methods have been implemented on the Diablo framework. Keywords security, protection, library interfaces, reverse engineering, Windows, Diablo I. INTRODUCTION WHEN a dynamic library is used in multiple applications, only one copy of the library has to be present in memory and on disk. This can result in significant savings in memory usage and disk space. The most important advantage however is in the area of software engineering. Subdividing an application into an executable and dynamic libraries makes it easier to reuse existing functionality from other applications and allows the components to be updated independently, because the interfaces between the components are fixed. These fixed interfaces are good targets for reverse engineering however, making it preferable to build statically linked applications. In a fully statically linked application the required parts of the system libraries are also a part of the executable and thus the application interacts directly with the kernel. Unfortunately, the interface provided by the Windows kernel differs between subsequent versions of Windows (and even between service packs). Consequently, applications use the interface provided by the system libraries (the Windows API) in stead, as this interface is guaranteed to be stable. As a result of the instability of the kernel interface, all Windows applications are dynamically linked and thus more susceptible to reverse engineering. II. REVERSE ENGINEERING Reverse engineering of software is the process of trying to understand an application at a higher level of abstraction from lower level information such as executable code. There are numerous reasons for reverse engineering an application, but here we will assume the role of the reverse engineer being filled by an attacker with malicious goals. In general there are two techniques a reverse engineer can use: static analysis and dynamic analysis. Static analysis is the process of analyzing an application without executing it. The executable file will be analyzed by disassembling the binary code it contains, constructing a control flow graph (CFG) and using this information to gain a deeper understanding of the application. In analyzing dynamically linked application the meta-information contained within the components can especially be of use. Meta-information is what we call the information present in these components that allow them to dynamically link with and use functionality from other components. Dynamic analysis on the other hand involves executing the application and observing its dynamic behavior in order to analyze it. A technique often used to analyze dynamically linked applications is hooking. Dynamically linked applications depend on components being found and used through their interfaces at runtime. A potential attacker can thus build a fake component that offers the same interface as a real component, and trick the application into using his component in stead of the real one. The fake component can then forward all function calls to the real component so the application continues executing normally and is unaware of any danger. However, the attacker would then be able to intercept all communication between the components, allowing him to reverse engineer the application more effectively. III. DIABLO Diablo is a link-time binary rewriting framework developed within CSL. Applications can be build on top of this framework, in our case we implemented two methods to protect a binary from reverse engineering on top of it. Diablo works at linker-level, which means that it takes the place of the linker in the build process. The object files generated by the compiler are taken by Diablo which uses it to emulate the linker process. This results in a binary that is the same as the original binary, but some information that is used by the linker and unrecoverable from the resulting binary will be kept. This information allows Diablo to build an accurate representation of the application upon which transformations and analysis can be applied. IV. ENCRYPTION OF META-INFORMATION The first implemented method is aimed at obstructing the use of meta-information during static analysis. As this information has to be present in the components in order to allow them dynamically link with other

6 components, we can t simply remove it. In stead Diablo rewrites the executable so the meta-information is still present, but in an encrypted form. On disk the executable will seem to have no interface with any other component, and there will be no meta-information present to use in static analysis. At runtime the application will use the encrypted meta-information to adjust itself and reconstruct the interfaces. As the interfaces are still present at runtime the application will still be vulnerable to dynamic analysis through hooking. V. STATIC LINKING From a security eye-point it would be preferable to make applications statically linked, as no metainformation would be present in the executable and hooking would be impossible. Therefore a second method was implemented that transforms a dynamically linked application into a statically linked one by linking the relevant portions of the dynamic libraries into the executable. To overcome the instability of the Windows kernel interface, the application adapts itself to the interface of the kernel on which it is running. This way we can enjoy the security advantages of static linking while retaining compatibility across different versions of Windows. VI. EVALUATION The methods were implemented as proof-of-concept and there are several limitations in the implementation that hinder the rewriting of realistic applications. The overhead introduced by the methods was evaluated and reckoned to be unnoticeable except in extreme cases. VII. CONCLUSION Dynamically linked applications are at an increased risk to reverse engineering. In this dissertation two methods to protect the use library interfaces between dynamically linked components against revere engineering were proposed and implemented. These methods are only proof-of-concept and can t yet be used to rewrite applications of a realistic scale, but the overhead they introduce is limited.

7 Inhoudsopgave 1 Inleiding Probleemstelling De dynamisch gelinkte softwarestapel Voor- en nadelen Statisch gelinkte softwarestapel Doelstellingen Overzicht Gerelateerd werk Linken Het buildproces Objectbestanden Het linkerproces Statisch linken versus dynamisch linken Diablo Werking Structuur Toepassingen Disassembleren Lineair disassembleren Recursief disassembleren IDA Pro Reverse engineering Statische analyse Dynamische analyse Bestaande oplossingen Het PE-formaat Dynamisch linken VII

8 2.5.2 Laden Rebasing De Windows-systeembibliotheken De verschillende API s Het API-set-schema De kernel-interface in Windows Systeemoproepen Syscall en sysenter Instabiliteit Systeemoproepen en systeembibliotheken WoW Encrypteren van meta-informatie De algemene werking Het encrypteren van de meta-informatie De glue code Aanpassingen in Diablo De initialisatiefunctie De laadfunctie Beperkingen en mogelijke uitbreidingen De eenrichtingsfuncties Uitbreiden ondersteuning uitvoerbare bestanden Dynamische aanvallen Statisch linken Toevoegen van DLL s Bepalen van de benodigde DLL s Reconstrueren van relocaties Disassembleren Implementatie van recursief disassembleren Sprongtabellen Statisch linken van dynamisch gelinkte bestanden Verwijderen van overbodige code en data Initialisatieroutines Partieel statisch linken Beperkingen en mogelijke uitbreidingen Iteratief bepalen van benodigde DLL s VIII

9 4.7.2 Opsplitsen data-secties Onderscheid code en data Initialisatie van de systeembibliotheken Compatibiliteit Algemene werking Glue code Aanpassingen in Diablo Initialisatiefunctie Laadfunctie Windows Beperkingen en mogelijk uitbreidingen Grafische systeemoproepen Verandering structuur SCW Veranderingen van system services bits Windows Implementatie Inwerken Encrypteren van meta-informatie Statisch linken Compatibiliteit SVN-statistieken Evaluatie Encrypteren van meta-informatie Statisch linken Beperkingen Nutteloze code en data Evaluatie overhead Conclusie 65 Bibliografie 66 IX

10 Hoofdstuk 1 Inleiding In dit inleidend hoofdstuk wordt het probleem dat deze scriptie poogt op te lossen in algemene bewoordingen uitgelegd. Er worden een aantal methodes voorgesteld om dit probleem op te lossen, en er wordt een overzicht gegeven van de rest van de scriptie. 1.1 Probleemstelling De dynamisch gelinkte softwarestapel We beginnen met een algemeen beeld te schetsen van een dynamisch gelinkte softwarestapel (zie Figuur 1.1). Onderaan vinden we de kernel, de belangrijkste component in de stack. De kernel beheert de machine en de bronnen waarover de machine beschikt. Hij zorgt ervoor dat meerdere applicaties tegelijkertijd op de machine kunnen uitvoeren zonder met elkaar te interfereren. De kernel voert uit in kernel-modus, dit houdt in dat hij de totale controle over de machine heeft. Applicaties voeren uit in user-modus, in deze modus zijn ze beperkt in hun acties. Als een applicatie een geprivilegieerde actie wil ondernemen (invoer van een muis krijgen, meer geheugenpagina s laten alloceren, uitvoer naar een scherm printen etc.) moet deze aan de kernel vragen om dit voor haar te doen d.m.v. systeemoproepen (system calls). Net boven de kernel vinden we de systeembibliotheken. Deze maken net als de kernel deel uit van het besturingssysteem en bieden functionaliteit aan die door de andere componenten uit de softwarestapel gebruikt kunnen worden. Zo bieden ze een abstractie aan van de systeemoproepen, zodat deze op een gemakkelijkere manier door andere componenten gebruikt kunnen worden. Naast deze abstractie bezitten ze ook eigen functionaliteit voor gebruik door andere componenten. Een applicatie (bv. een tekstverwerker, een kalender of een internet browser) bestaat uit een uitvoerbaar bestand ( APP op de figuur) en de dynamische bibliotheken waarvan dit bestand afhankelijk is. Deze bibliotheken kunnen zowel systeembibliotheken als andere dynamische bibliotheken (ontwikkeld door de ontwikkelaar(s) van de applicatie of door een derde partij, LIB op de figuur) zijn. Om hun functionaliteit ten dienste van andere componenten te stellen bieden deze dynamische bibliotheken een interface aan die aan bepaalde conventies voldoet en stabiel (t.t.z. niet veranderd) is. Als laatste bespreken we de stuurprogramma s (drivers). Een stuurprogramma stuurt een spe- 1

11 Figuur 1.1: Een algemeen beeld van een dynamisch gelinkte softwarestapel. cifiek stuk hardware (zoals een muis, een toetsenbord of een beeldscherm) aan, en kan invoer ophalen van dit stuk hardware of uitvoer ernaartoe sturen. Stuurprogramma s kunnen zowel in kernel- als in user-modus uitvoeren. Dit hangt af van de situatie en het besturingssysteem Voor- en nadelen Een dynamisch gelinkte softwarestapel heeft een aantal voordelen. Doordat de interface tussen dynamisch gelinkte componenten vast staat, kan één van deze componenten gemakkelijk vervangen worden door een andere component met dezelfde interface. Een dynamische bibliotheek kan bijvoorbeeld vervangen worden door een nieuwere versie van deze bibliotheek waarin een aantal bugfixes zijn gebeurd, zonder dat de andere componenten die er afhankelijk van zijn aangepast moeten worden. Doordat meerdere applicaties van eenzelfde dynamische bibliotheek gebruik kunnen maken, wordt er ook uitgespaard op vlak van opslagruimte en geheugengebruik. Een goed voorbeeld hiervan zijn de systeembibliotheken. Deze worden door quasi elke applicatie op het systeem gebruikt, maar er is slechts één kopie van aanwezig in het geheugen en op de harde schijf. Het gebruik van dynamisch linken heeft echter ook een aantal nadelen. In deze scriptie zullen we vooral aandacht besteden aan nadelen op vlak van beveiliging. Zo zijn de interfaces van dynamische bibliotheken perfecte aanknopingspunten om aan reverse engineering te doen. Deze aanknopingspunten zijn bij verschillende vormen van reverse engineering nuttig. We onderscheiden twee vormen van reverse engineering: bij statische analyse wordt de applicatie geanalyseerd zonder ze (ook echt) uit te voeren, bij dynamische analyse wordt ze wel uitgevoerd. Om het gebruik van elkaars interfaces toe te laten, bezitten de componenten meta-informatie die gebruikt kan worden tijdens statische analyse. Aangezien de interface van een component gekend is, kan een potentiële aanvaller een valse 2

12 Figuur 1.2: Een voorbeeld van een hook. Figuur 1.3: Een algemeen beeld van een statisch gelinkte softwarestapel. component construeren die dezelfde interface aanbiedt als de echte component, en andere componenten deze valse component laten gebruiken in plaats van de echte component. De valse component kan alle functieoproepen doorsturen naar de echte component. Op deze manier blijft de applicatie werken en lijkt het alsof er niets mis is, maar de aanvaller is nu goed geplaatst om de communicatie tussen de twee echte componenten af te luisteren. Deze techniek wordt vaak gebruikt bij dynamisch analyse. We noemen dit hooking. Een voorbeeld hiervan valt te zien op Figuur 1.2. De hook aanwezig tussen applicatie en bibliotheek is rood gekleurd Statisch gelinkte softwarestapel Een mogelijke oplossing is om de applicatie volledig statisch te linken (zie Figuur 1.3). Alle componenten waaruit de applicatie bestaat zijn nu samengevoegd tot één grote component. Deze is enkel afhankelijk van de kernel zelf, en maakt geen gebruik van dynamische interfaces. De beveiligingsnadelen van dynamisch linken zijn dus niet meer aanwezig. Nu we een applicatie hebben die rechtstreeks afhankelijk is van de kernel, moeten we ons wel 3

13 Figuur 1.4: De instabiele kernel-interface op Windows. vragen beginnen stellen over de stabiliteit van de interface tussen de applicatie en de kernel (de kernel-interface). Een ontwikkelaar wil natuurlijk dat zijn applicatie op verschillende versies van het besturingssysteem werkt. Als er een nieuwe versie van het besturingssysteem uitkomt met een nieuwe kernel dan willen we dat de applicatie ook op deze nieuwe versie werkt. Omdat een volledig statisch gelinkte applicatie rechtstreeks gebruik maakt van de kernel-interface, willen we dus ook dat de kernel-interface achterwaarts-compatibel is. Op Linux is dit het geval [1]. De kernel-interface kan wel uitbreiden, maar verandert voor de rest niet. Op Windows daarentegen is de kernel-interface niet stabiel (zie Figuur 1.4). Een volledig statisch gelinkte applicatie zal dus enkel werken op die versie van Windows waarvoor ze gelinkt is. Applicaties die met meerdere versies van Windows compatibel willen zijn, moeten daarom de systeembibliotheken gebruiken. Aangezien deze deel uitmaken van het besturingssysteem zijn ze aangepast om gebruik te maken van de specifieke versie van de kernel-interface, en de interface die de systeembibliotheken aanbieden is wel stabiel. Door het gebruik van bibliotheekinterfaces is de applicatie wel kwetsbaarder voor reverse engineering, wat we eigenlijk wilden voorkomen. 1.2 Doelstellingen In deze scriptie worden twee methodes gepresenteerd om uitvoerbare bestanden te herschrijven met als doel hun gebruik van bibliotheekinterfaces af te schermen tegen reverse engineering. De uitvoerbare bestanden die worden herschreven zijn meer bepaald 32-bits uitvoerbare bestanden geschreven voor de x86-versie van Windows. In de eerste methode wordt de meta-informatie geëncrypteerd. Het gebruik van bibliotheekinterfaces wordt zo verborgen en statische analyse wordt tegengegaan. Omdat de interfaces tijdens de uitvoering nog steeds gebruikt worden, blijft de applicatie wel kwetsbaar voor hooking. In de tweede methode wordt de applicatie volledig statisch gelinkt. Dit gebeurt door die delen van de dynamische bibliotheken die de applicatie gebruikt toe te voegen aan het uitvoerbaar bestand. De bibliotheekinterfaces zijn dan verdwenen en het uitvoerbaar bestand is enkel afhankelijk van de kernel. Om met de instabiliteit van de kernel-interface overweg te kunnen, is de applicatie in staat zichzelf tijdens de uitvoering aan te passen aan de specifieke versie van de kernel waarop ze uitgevoerd wordt. Zo wordt ook dynamische analyse tegengegaan. 4

14 Om uitvoerbare bestanden te herschrijven maken we gebruik van het Diablo-raamwerk. Dit binnen CSL ontwikkelde raamwerk maakt het mogelijk om uitvoerbare bestanden op het niveau van de linker te herschrijven. Bij de op Diablo geïmplementeerde toepassingen beschikt men normaal gezien over de broncode van de applicatie of over de objectbestanden waaruit de applicatie is opgebouwd. We beschikken echter over broncode noch objectbestanden voor de dynamische bibliotheken die we in de tweede methode willen toevoegen aan het uitvoerbaar bestand. Deze fundamentele beperking leidt tot een aantal problemen in de implementatie. 1.3 Overzicht In Hoofdstuk 2 wordt het gerelateerd werk besproken en wordt de probleemstelling uitgediept. Vervolgens wordt in Hoofdstuk 3 de eerste eerder besproken methode voorgesteld. De tweede methode wordt in twee hoofdstukken uitgelegd: Hoofdstuk 4 gaat over het eigenlijke statisch linken, en Hoofdstuk 5 over het verzorgen van compatibiliteit met verschillende versies van Windows. In Hoofdstuk 6 wordt het werk geleverd tijdens de implementatie besproken. De twee methoden worden geëvalueerd in Hoofdstuk 7 en de scriptie wordt besloten met een conclusie in Hoofdstuk 8. 5

15 Hoofdstuk 2 Gerelateerd werk Dit hoofdstuk bestaat uit twee grote delen. In het eerste deel wordt gerelateerd werk besproken dat meer algemeen is, het tweede deel is daarentegen Windows-specifiek. Van een aantal onderwerpen uit het eerste deel wordt toegelicht hoe deze op Windows werken, en er wordt meer Windows-specifieke informatie gegeven waarvan gebruik gemaakt wordt in de rest van de scriptie. 2.1 Linken Aangezien we bestanden op linkerniveau gaan herschrijven, krijgen we te maken met een proces waar in hedendaagse opleidingen snel aan voorbijgegaan wordt: dat van het linken. In deze sectie bespreken we kort de manier waarop een uitvoerbaar bestand gegenereerd wordt en de rol die de linker daarin speelt in Figuur 2.1. Het merendeel van de sectie is gebaseerd op Levine s boek Linkers & Loaders [2] Het buildproces Het genereren van een uitvoerbaar bestand op basis van broncode in een bepaalde programmeertaal het buildproces gebeurt in een aantal stappen. Twee belangrijke stappen zijn die van het compileren (uitgevoerd door de compiler) en het linken (uitgevoerd door de linker). Als voorbeeld beschouwen we een op Windows uitvoerbaar bestand dat gegenereerd wordt op basis van C-broncode (zie Figuur 2.1). Per bronbestand wordt er door de compiler een objectbestand gegenereerd. Dit bestand bevat de instructies en plaats voor de al dan niet geïnitialiseerde statische variabelen. De objectbestanden die de compiler gegenereerd heeft dienen vervolgens als invoer voor de linker, die deze combineert tot het uitvoerbaar bestand. Niet enkel de net gegenereerde objectbestanden dienen als invoer. Er wordt namelijk ook gebruik gemaakt van bibliotheken. Een bibliotheek is een verzameling reeds gecompileerde code die hergebruikt kan worden door meerdere applicaties. Ons voorbeeld maakt zoals quasi alle applicaties geschreven in C gebruik van de C-standaardbibliotheek, waarin men de functies printf, malloc, abs etc. vindt. 6

16 Figuur 2.1: Een compiler zet bronbestanden om in objectbestanden, die de linker combineert tot een uitvoerbaar bestand Objectbestanden Een objectbestand bestaat uit headers (die de rest van het bestand beschrijven), een aantal secties met verschillende eigenschappen, en informatie die enkel gebruikt wordt bij het linken. Er bestaan verschillende secties: de.text-sectie: in deze sectie vinden we de uitvoerbare code. de.data-sectie: deze sectie bevat data die zowel leesbaar als schrijfbaar is. de.rdata-sectie: de data in deze sectie is leesbaar, maar niet schrijfbaar. De inhoud van de sectie blijft dus hetzelfde doorheen de hele uitvoering van de applicatie. de.bss-sectie: in tegenstelling tot andere secties is deze sectie niet echt aanwezig in het bestand. De sectie bevat data waarvan de waarde op nul geïnitialiseerd wordt en is zowel leesbaar als schrijfbaar. Aangezien geweten is dat de sectie enkel nullen bevat, houden we in de headers enkel de grootte ervan bij zonder de sectie zelf te includeren in het bestand. Als een uitvoerbaar bestand met een.bss-sectie in het geheugen geladen wordt zal er een sectie met de juiste grootte gecreëerd en op nul geïnitialiseerd worden. Alle secties die enkel doorgaans enkel data bevat (zoals.data,.rdata en.bss) noemen we data-secties. Een objectbestand bevat twee soorten informatie waarvan de linker gebruik maakt: symboolinformatie en relocatie-informatie. Een symbool is de naam van een functie of een variabele 7

17 Figuur 2.2: Een voorbeeld van een aantal relocaties. die gedefinieerd wordt in een objectbestand. Een objectbestand bevat enerzijds informatie over symbolen die in het objectbestand zelf gedefinieerd worden en anderzijds over symbolen die geïmporteerd moeten worden uit andere objectbestanden (of die gedefinieerd worden door de linker). Stel bijvoorbeeld dat de functie foo geïmplementeerd wordt in foo.obj, en aangeroepen wordt vanuit main.obj. Dan is foo een symbool dat gedefinieerd is in foo.obj, en geïmporteerd wordt in main.obj. Binnenin een objectbestand zijn er plaatsen in de ene sectie die plaatsen in een andere sectie refereren. Als we bijvoorbeeld een functie hebben die een statisch gealloceerde variabele incrementeert, leidt dit tot een instructie in de.text-sectie waarvan het operand een adres in de.data-sectie is. Deze referenties worden in het uiteindelijke uitvoerbaar bestand voorgesteld als adressen. Op het moment dat de compiler het objectbestand genereert kunnen deze adressen nog niet berekend worden. Dit gebeurt later door de linker in een proces genaamd relocatie. Om deze adressen te kunnen berekenen wordt er relocatie-informatie bijgehouden, deze bestaat uit een lijst van relocaties die moeten gebeuren. Het voorbeeld met de statisch gealloceerde variabele leidt tot een relocatie die voorgesteld wordt op Figuur 2.2. Het adres gebruikt door de inc-instructie is nog niet berekend en staat in het rood. Er wijst wel een relocatie van deze operand naar de offset (offsetnaar1 ) binnen de.data-sectie waarop de variabele zich bevindt. Zodra het uiteindelijke adres van de.data-sectie gekend is, wordt het adres van de variabele berekend en weggeschreven op de positie van de operand. In de relocatie-informatie wordt de positie van deze operand ook voorgesteld als een offset binnen een sectie. Relocaties komen niet enkel voor tussen secties, een relocatie kan ook wijzen van een plaats binnen een sectie naar een symbool. Het adres van het symbool dat gevonden moet worden door de linker wordt dan weggeschreven op de plaats binnen de sectie. Op Figuur 2.2 wijst de onderste relocatie naar een symbool Het linkerproces In deze sectie wordt het linkerproces voorgesteld zoals het verloopt indien er statisch gelinkt wordt. Tijdens het linkerproces worden alle objectbestanden samengevoegd tot een uitvoerbaar bestand, en worden de uiteindelijke adressen berekend. De eerste fase in dit proces is die van symboolresolutie. Voor alle in objectbestanden geïmporteerde symbolen moeten er definities gevonden worden. Een definitie specificeert een bepaalde offset binnen een bepaalde sectie waarop een symbool gevonden kan worden. Indien een symbool door een bepaald objectbestand geïmporteerd wordt maar nergens of meerdere keren gedefinieerd wordt, leidt 8

18 dit tot een linkerfout. Alle gelijknamige secties uit de objectbestanden worden samengevoegd zodat er nog maar één.text-sectie, één.data-sectie etc. overblijft. Naast het uitvoerbaar bestand kan de linker ook nog de zogenaamde linker map genereren. Hierin valt onder meer te vinden op welk adres binnen de resulterende secties de oorspronkelijke secties (of subsecties) uit de objectbestanden geplaatst zijn. Daarna worden de eigenlijke relocaties uitgevoerd. De adressen worden berekend en weggeschreven, ook voor geïmporteerde symbolen. Tijdens de symboolresolutie zijn alle relocaties die naar een symbool wijzen namelijk al vertaald naar relocaties die naar een offset binnen een sectie wijzen. Het eindresultaat van dit proces is een uitvoerbaar bestand waarin alle symbooladressen berekend zijn en waaruit de symboolinformatie dus kan verwijderd worden. Zoals gezegd is dit alles enkel van toepassing indien we volledig statisch linken. Indien we dynamisch linken is het namelijk nog mogelijk om tijdens de uitvoering symbolen op te zoeken Statisch linken versus dynamisch linken De procedure die in Sectie werd besproken is die van het statisch linken. Een volledig statisch gelinkt uitvoerbaar bestand moet geen symboolinformatie meer bevatten omdat alle symbolen reeds gevonden zijn, en het is niet afhankelijk van andere componenten (uitgezonderd de kernel). Het uitvoerbaar bestand kan echter ook dynamisch gelinkt zijn. In dit geval bevat het wel nog symboolinformatie de zogeheten meta-informatie die het de applicatie mogelijk maakt om tijdens de uitvoering (of dynamisch ) symbolen op te zoeken in dynamische bibliotheken en deze te gebruiken. Deze dynamische bibliotheken worden bij het opstarten van de applicatie in de adresruimte van de applicatie geladen. Als er andere applicaties opstarten die gebruik maken van eenzelfde bibliotheek wordt deze in alle gerelateerde adresruimtes geladen op copy-on-write pagina s. Dit wil zeggen dat alle processen eenzelfde fysieke geheugenpagina delen, tenzij ze er zelf aanpassingen op aanbrengen. Zodra een proces een copy-on-write pagina beschrijft, wordt deze gekopieerd naar een pagina die enkel door dat specifieke proces gebruikt wordt. Het gebruik van dynamisch linken heeft zijn voordelen. Het voornaamste voordeel is op vlak van software engineering. Delen van een applicatie kunnen op een gemakkelijke wijze hergebruikt worden in een andere applicatie (zelfs delen die door iemand anders ontwikkeld zijn). Als meerdere applicaties eenzelfde dynamisch bibliotheek gebruiken is er maar één fysieke kopie van die bibliotheek aanwezig op de harde schijf, en bij het uitvoeren meestal maar één kopie in het fysieke geheugen. Het eigenlijke uitvoerbaar bestand is ook kleiner aangezien er meer code en data aanwezig is in dynamische bibliotheken, en deze bibliotheken kunnen geüpdatet worden zonder dat er iets moet veranderen aan het uitvoerbaar bestand. Er zijn echter ook nadelen aan het gebruik van dynamisch linken verbonden. Dynamische gelinkte applicaties presteren iets slechter vanwege indirectie (voor het specifieke geval van 9

19 Windows wordt dit uitgelegd in Sectie 2.5.2, en verschillende versies van eenzelfde dynamische bibliotheek kunnen leiden tot compatibiliteitsproblemen (e.g. DLL hell [3]). Daarnaast is er nu meta-informatie aanwezig in de bestanden die gebruikt kan worden bij statische analyse van de applicatie. Bovendien is het vertrouwen op componenten die dynamisch gevonden worden gevaarlijk. Dit maakt namelijk een nieuwe klasse aan aanvallen mogelijk die gebruikt kunnen worden bij dynamische analyse. Voor deze scriptie zijn vooral deze twee laatste nadelen van belang. 2.2 Diablo De linker is de eerste component in het buildproces van een applicatie die het overzicht heeft over het volledige uitvoerbare bestand. In het bestand dat de linker produceert is de relocatie-informatie die in het linkerproces gebruikt wordt niet meer aanwezig. De symboolinformatie kan die niet met dynamisch symbolen te maken heeft kan ook verwijderd zijn. Als we uitvoerbare bestanden willen herschrijven door enkel gebruik te maken van de uitvoerbare bestanden zelf, beschikken we dus over minder informatie. Bijgevolg is een tool die op linkerniveau werkt in de beste positie om over de grenzen van de oorspronkelijke objectbestanden heen optimalisaties toe te passen en uitvoerbare bestanden te herschrijven. Een voorbeeld hiervan is het Diablo-raamwerk, dat in deze scriptie gebruikt wordt [4] Werking De eerste stap die Diablo onderneemt bij het herschrijven van een uitvoerbaar bestand is het linkerproces emuleren. Hiervoor wordt gebruik gemaakt van de objectbestanden die als invoer dienden bij het oorspronkelijke linkerproces en van de linker map die bij dit proces gegenereerd werd (zie Sectie 2.1.3). Tijdens het emuleren wordt er een parent-object (dat een voorstelling van het uitvoerbaar bestand vormt) opgebouwd uit de objectbestanden. Dit parent-object bestaat uit parent-secties die opgebouwd zijn uit secties afkomstig van de verschillende objectbestanden (zogenaamde subsecties). De symbool- en relocatie-informatie uit de objectbestanden wordt gebruikt om de adressen binnen het parent-object te berekenen, en vervolgens door Diablo in datastructuren bijgehouden. Uiteindelijk wordt er gecontroleerd of het resultaat van het geëmuleerde linkerproces overeenkomt met het te herschrijven bestand. Vervolgens worden alle.text-secties in het parent-object gedisassembleerd en wordt er een controleverloopgraaf opgesteld op basis van de gedisassembleerde instructies en de relocatieinformatie. Deze controleverloopgraaf is een gerichte graaf met knopen en pijlen. Aan de hand van de relocatie-informatie wordt er ook een gerichte graaf opgebouwd die de afhankelijkheden tussen de verschillende data-secties voorstelt. Deze twee grafen samen noemen we de aangevulde controleverloopgraaf of ACVG, die als een representatie van de applicatie dient. Het is deze representatie die we zullen aanpassen om de applicatie te herschrijven. Diablo zal dan op basis van de aangepaste representatie een nieuw, herschreven uitvoerbaar bestand genereren. De controleverloopgraaf opgebouwd door Diablo bevat als knopen basisblokken of BBL s. Een BBL is een blok van instructies die altijd samen uitgevoerd worden. Dit impliceert dat 10

20 Figuur 2.3: Een voorbeeld van een deel van een controleverloopgraaf. enkel de eerste instructie in het blok het doel kan zijn van een controleverloopinstructie, en dat enkel de laatste instructie in het blok een controleverloopinstructie kan zijn. Het BBL dat het beginpunt van de applicatie vormt, wordt de beginknoop van de controleverloopgraaf genoemd. De pijlen in de graaf stellen het controleverloop voor. Zo zijn er sprong-pijlen die een sprong van één BBL naar een andere BBL voorstellen. Een conditionele sprong wordt voorgesteld door twee pijlen die vertrekken vanuit het BBL: een sprong-pijl voor het geval waarin de sprong genomen wordt en een doorval-pijl voor het geval waarin de sprong niet genomen wordt (het doorvalpad). Een functieoproep wordt voorgesteld door een call-pijl die van een BBL met als laatste instructie een functieoproep naar het eerste BBL van de opgeroepen functie gaat. Deze call-pijl heeft een corresponderende return-pijl die van het laatste BBL van de functie naar het BBL volgende op die met de functieoproep gaat. Figuur 2.3 toont een deel van een controleverloopgraaf. De groene pijlen zijn sprong-pijlen, de zwarte zijn doorval-pijlen en de rode is een call-pijl. Indien het doel van een controleverloopinstructie een register of een adres opgeslagen in het geheugen is, dan spreken we over indirect controleverloop. Het uiteindelijke doeladres (en bijhorende BBL) kan in dat geval niet altijd door Diablo bepaald worden. Dit wordt binnen de controleverloopgraaf gemodelleerd d.m.v. een helleknoop. In deze knoop komen pijlen toe vanuit alle BBL s die resulteren in indirect controleverloop, en er gaan pijlen vanuit de helleknoop naar alle BBL s die een doel kunnen zijn van indirect controleverloop. 11

21 Eens de controleverloopgraaf opgebouwd is, wordt deze onderverdeeld in functies. Deze functies zijn groepen van BBL s die ruwweg overeenkomen met de oorspronkelijke procedures in de applicaties. Het onderverdelen in functies gebeurt door de controleverloopgraaf te overlopen (beginnende vanaf het beginpunt van de applicatie) en te zoeken naar call-pijlen Structuur Diablo kan bestanden herschrijven die bedoeld zijn voor verschillende platformen en verschillende architecturen. Om dit mogelijk te maken bestaat het raamwerk uit een algemeen gedeelte en een aantal platform- en architectuur-specifieke backends. Er bestaan verschillende formaten voor uitvoerbare bestanden en objectbestanden, zoals het PE-formaat gebruikt op Windows en het ELF-formaat gebruikt op Linux. Voor het inlezen van deze bestanden bezit Diablo dus een PE-backend en een ELF-backend. Het emuleren van het linkerproces gebeurt gebeurt bijvoorbeeld grotendeels in algemene code, maar om de.text-secties te disassembleren wordt er gebruik gemaakt van architectuur-specifieke backends. In deze scriptie wordt er gebruik gemaakt van de i386 -backend (i386 is een andere naam voor x86). Op dit raamwerk kunnen er applicaties gebouwd worden. Een voorstelling van zo n Diablogebaseerde applicatie met het Diablo-raamwerk en zijn backends valt te zien op Figuur 2.4. In het kader van deze masterproef heb ik een Diablo-gebaseerde applicatie geschreven Toepassingen Diablo is doorheen de jaren voor veel verschillende toepassingen gebruikt, enkele hiervan worden kort besproken. Een eerste toepassing is compactie na het linken, waarbij Diablo gebruikt wordt om uitvoerbare bestanden te verkleinen [4][5][6]. Voor een doorsnee uitvoerbaar bestand zijn er in de door Diablo opgebouwde ACVG knopen aanwezig die niet bereikbaar zijn vanaf de beginknoop. Elke onbereikbare knoop die een BBL is, bestaat uit instructies die niet bereikbaar zijn vanuit het beginpunt en dus nooit uitgevoerd kunnen worden. Elke onbereikbare knoop die een subsectie is, bestaat uit data die tijdens de uitvoering van de applicatie onmogelijk gebruikt kan worden. Onbereikbare knopen kunnen dus zonder problemen door Diablo verwijderd worden om een kleiner uitvoerbaar bestand te bekomen. We noemen dit het elimineren van onbereikbare code en data. Er zijn in Diablo nog verdere optimalisaties en analyses geïmplementeerd die het mogelijk maken een uitvoerbaar bestand nog meer te verkleinen, maar die zijn voor deze scriptie niet van belang [5][6]. Uitvoerbare bestanden kunnen ook herschreven worden met het oog op beveiliging. Zo is Diablo gebruikt om herschreven uitvoerbare bestanden te genereren die zichzelf dynamisch aanpassen [7]. Deze techniek zorgt ervoor dat een bepaald geheugenbereik meerdere, verschillende code-sequenties bevat doorheen de uitvoering van de applicatie. Op deze manier wordt het moeilijker voor een potentiële aanvaller om aan reverse engineering te doen. Diablo wordt ook gebruikt om aan code-diversificatie te doen [8]. Het doel is hier om patch-gebaseerde exploits tegen te gaan door op basis van eenzelfde broncode uitvoerbare bestanden te genereren die op vlak van uitvoerbare code sterk verschillen. Om dit bereiken wordt on- 12

22 Figuur 2.4: De structuur van een Diablo-gebaseerde applicatie[4]. der meer de controleverloopgraaf sterk aangepast en wordt direct controleverloop verborgen achter indirect controleverloop. 2.3 Disassembleren Als we willen weten welke instructies er in een.text-sectie zitten moeten we deze disassembleren. Dit kan op twee manieren: lineair of recursief, met elk zijn eigen voor- en nadelen [9] Lineair disassembleren Een eerste manier om een.text-sectie te disassembleren is lineair disassembleren. Dit houdt in dat er, vanaf het beginadres van de sectie, instructie per instructie gedisassembleerd wordt. Op het beginadres van de sectie disassembleren we de eerste instructie en determineren zijn lengte. Zo krijgen we het adres van de volgende instructie, die op zijn beurt disassembleren enzoverder. De aard van de gedisassembleerde instructies is hierbij niet van belang. 13

23 Figuur 2.5: Een voorbeeld van het lineair disassembleren van een.text-sectie waarin data aanwezig is. Deze manier van disassembleren is gemakkelijk te implementeren, maar komt in de problemen indien er data aanwezig is in de.text-sectie. In Figuur 2.5 bijvoorbeeld wordt de functie GeefVijfTerug geëxporteerd. Deze maakt gebruik van de interne functie GeefEenterug en de gebruikte variabelen zijn als data tussen de twee functies in opgeslagen. Indien we hier vanaf het begin van de sectie lineair beginnen te disassembleren, dan worden de data bytes als instructiebytes aanzien en tot valse instructies gedisassembleerd. Dit zou geen groot probleem vormen in het geval van een RISC-instructieset, waar alle instructies dezelfde lengte hebben. De x86-architectuur heeft echter een CISC-instructieset waarbij instructies een verschillende lengte hebben. Bij het disassembleren van de databytes kan het gebeuren dat er een instructie gedisassembleerd wordt die zowel data- als echte instructiebytes bevat, met als gevolg dat de daaropvolgende gedisassembleerde instructies niet overeenkomen met de eigenlijke instructies Recursief disassembleren Bij recursief disassembleren beginnen we met disassembleren op adressen waarvan we zeker weten dat er instructies op te vinden zijn, zoals het beginadres van een applicatie, het adres van de initialisatieroutine van een bibliotheek, en de adressen van geëxporteerde functies. Van op elk van deze adressen beginnen we met instructies lineair te disassembleren, met dat verschil dat in het geval dat de net gedisassembleerde instructie een controleverloopinstructie is, we het controleverloop zullen volgen. Op deze manier proberen we te voorkomen dat data verkeerdelijk gedisassembleerd wordt tot instructies. In Figuur 2.6 zien we een voorbeeld van recursief disassembleren. De enige geëxporteerde functie is GeefVijfTerug. Er wordt begonnen met disassembleren op het adres van deze functie, het controleverloop wordt gevolgd, alle instructies worden gedisassembleerd en de data niet. Indien de uitvoerbare code geobfusceerd is, is het wel mogelijk dat er data verkeerdelijk gedisassembleerd wordt [10]. Er kunnen bijvoorbeeld conditionele sprongen geïntroduceerd worden die eigenlijk altijd genomen of nooit genomen worden. Als het beginadres van het pad dat eigenlijk nooit genomen wordt data bevat, blijft de applicatie correct uitvoeren maar wordt er 14

24 Figuur 2.6: Een voorbeeld van het recursief disassembleren van een.text-sectie, met stappen genummerd in volgorde. verkeerdelijk data gedisassembleerd. Net zoals bij het opstellen van een controleverloopgraaf vormt indirect controleverloop een struikelblok voor het recursief disassembleren. Indien we bijvoorbeeld een call eax -instructie tegenkomen dan kan het controleverloop meestal niet gevolgd worden (tenzij eventueel via constantenpropagatie). Van alle adressen waarop er geen instructies gedisassembleerd zijn, wordt er verwacht dat deze data bevatten. Vanwege indirect controleverloop worden er bij recursief disassembleren dus veel instructies niet gedisassembleerd en beschouwd als data. In principe zou een methode die voor alle mogelijke.text-secties de aanwezige code en data perfect kan onderscheiden ook in staat zijn het stopprobleem op te lossen. Bijgevolg kunnen we onmogelijk zo n methode construeren [11] IDA Pro IDA Pro (Interactive Disassembler Professional) is een populaire, recursieve disassembler die m.b.v. een aantal bijkomende technieken een zeer goede nauwkeurigheid in het onderscheiden van code en data haalt [12]. Eén van deze technieken is Fast Library Identification and Recognition Technology of FLIRT. Dit houdt in dat statisch gelinkte code die afkomstig is uit bibliotheken gemakkelijk herkend wordt a.d.h.v. een databank met signaturen van gekende functies. Het herkennen van deze reeds gekende functies beperkt het werk dat IDA levert bij het disassembleren van een uitvoerbaar bestand, en vergemakkelijkt ook het werk van een reverse engineer. De werking van deze gekende functies is namelijk duidelijk uitgelegd in specificaties en handleidingen. Reverse engineering is dus niet meer nodig. Daarnaast wordt er ook gebruik gemaakt van heuristieken om pointers naar code te herkennen [12]. Op deze wijze kunnen ook bepaalde instructies die enkel via indirect controleverloop bereikbaar zijn gedisassembleerd worden. IDA Pro maakt ook gebruik van PDB-bestanden (Program DataBase). Een PDB-bestand bevat debugging-informatie voor een specifiek PE-bestand, zoals ongeëxporteerde symbolen. Voor DLL s van Microsoft-makelij zijn de bijhorende PDB-bestanden online te vinden. IDA download deze automatisch en gebruikt ze om tot een beter resultaat te komen. 15

25 2.4 Reverse engineering Reverse engineering van software is het proberen te begrijpen hoe een applicatie op een hoger niveau werkt [13]. Om dit te doen beschikt een reverse engineer doorgaans enkel over het uitvoerbaar bestand en de verwante dynamische bibliotheken, beiden bestaande uit uitvoerbare code en data. Er zijn verschillende redenen om aan reverse engineering te doen, zowel goedaardig als kwaadaardig. De ontwikkelaars van de applicatie kunnen proberen hun eigen verloren gegane broncode te reconstrueren, of een aanvaller kan een poging wagen om beschermde algoritmes of datastructuren aanwezig in een uitvoerbaar bestand te kopiëren en te gebruiken voor zijn eigen doeleinden. Antivirus-software kan proberen te achterhalen of een uitvoerbaar bestand kwaadaardige doeleinden heeft. Verder zijn er tools die bugs in applicaties opsporen zodat deze gefixed kunnen worden, maar aanvallers kunnen deze zwakheden (en een verbeterd begrip van de werking van de applicatie) omzetten in een succesvolle exploit. Reverse engineering kan op twee manieren: statische analyse en dynamische analyse Statische analyse Bij statische analyse wordt een applicatie geanalyseerd zonder deze ook daadwerkelijk uit te voeren. Er wordt dus gekeken naar de uitvoerbare code in het uitvoerbaar bestand. Deze wordt gedisassembleerd en er wordt een controleverloopgraaf opgesteld. De resulterende statische representatie van de applicatie wordt gebruikt om met de hand of automatisch de applicatie te analyseren. Hierbij komt symboolinformatie aanwezig in het bestand (om dynamische symbolen te gebruiken of om debuggen gemakkelijker te maken) van pas. Het gebruik van dynamische symbolen (meta-informatie) in een functie helpt een reverse engineer deze functie te begrijpen indien de betekenis van dit symbool gekend is. Aangezien symbolen namen van functies of variabelen zijn, kan symboolinformatie op zich al veelzeggend zijn. Het is bijvoorbeeld duidelijk wat een oproep naar de functie CreateFile doet. Doordat de interface aangeboden door een dynamische bibliotheek vast staat, zal een oproep naar deze functie vanuit eender welk bestand in de toekomst ook altijd hetzelfde blijven doen. Statische analyse heeft echter zijn beperkingen als het gaat om begrijpen wat een bepaald stuk code doet. Virusscanners kunnen malware bijvoorbeeld detecteren door in uitvoerbare code patronen te herkennen die geassocieerd zijn met gekende malware [14], maar deze methode kan niet overweg met polymorfisme. Polymorfisme houdt in dat er vele verschillende versies van één virus worden gegenereerd die allen hetzelfde gedrag hebben, maar syntactisch verschillen [15]. Daarnaast gaat statische analyse er ook van uit dat het statische en dynamische beeld van een applicatie overeenkomen, wat niet per se zo is. De uitvoerbare code in een uitvoerbaar bestand kan dynamisch aangepast worden [7], en zowel het disassembleren van uitvoerbare code als het opstellen van een controleverloopgraaf kan bemoeilijkt worden d.m.v. obfuscatie [16] [10]. Een goede reverse engineer maakt dus ook gebruik van dynamische analyse. 16

26 2.4.2 Dynamische analyse Dynamische analyse houdt in dat we een applicatie analyseren terwijl ze uitvoert. Dit kan nieuwe inzichten verschaffen en een aantal problemen waar statische analyse last van heeft oplossen, maar het is in het algemeen ook meer werk. Malware kan bijvoorbeeld statische analyse bemoeilijken, maar door ze in een beschermde omgeving uit te voeren kan de malware wel gemakkelijk dynamisch geanalyseerd worden [17][18]. In tegenstelling tot statische analyse is de vergaarde informatie wel enkel geldig voor een specifieke uitvoering van de applicatie, en ze levert dus geen volledig beeld van de applicatie [19]. Een techniek die vaak gebruikt wordt tijdens dynamische analyse is API-hooking [20]. Omdat de interface aangeboden door een dynamische bibliotheek gekend is, kan een reverse engineer zelf een bibliotheek maken die een deel van dezelfde interface aanbiedt. De reverse engineer kan er dan voor zorgen dat zijn eigen bibliotheek gebruikt wordt in plaats van de oorspronkelijke bibliotheek, en kan zo op een gemakkelijk manier zijn eigen code laten uitvoeren in een applicatie. De geplaatste hooks laten ook toe dynamisch het gebruik van functies uit bibliotheken waar te nemen (op het einde van de geplaatste hook moeten de echte functies dan ook opgeroepen worden om een correct verloop van de applicatie te verzekeren) Bestaande oplossingen Als we een applicatie willen beschermen tegen reverse engineering kunnen we gebruik maken van obfuscatie [21]. Een ontwikkelaar kan echter enkel die componenten die hij zelf levert obfusceren. Obfuscatie is dus geen volledige oplossing voor een dynamisch gelinkte applicatie, doordat deze nog steeds kwetsbaar is aan de interfaces (vanwege de meta-informatie en APIhooking). Een logische oplossing is dus om het aantal interfaces te verkleinen, door minder dynamische bibliotheken te gebruiken en meer statisch te linken. Het liefst zouden we volledig statisch gelinkte applicaties gebruiken, maar die zijn niet compatibel met meerdere versies van Windows (zie Sectie 2.7). Prelinking is een proces op Linux waarbij de indeling van de adresruimte van een proces al statisch (voor de uitvoering) vastgelegd wordt [22]. De adressen van de dynamische bibliotheken (en hun geëxporteerde symbolen) binnen de adresruimte van het proces liggen al vast en kunnen dus op de juiste plaatsen weggeschreven worden. De applicatie zal bijgevolg sneller opstarten omdat deze adressen niet meer dynamisch berekend moeten worden. Indien sommige adressen niet up-to-date zijn (omdat een dynamische bibliotheek veranderd is t.o.v. diegene waartegen er gelinkt werd) worden deze opnieuw berekend. Import Binding is een gelijkaardig proces op Windows [23]. Deze processen zorgen ervoor dat dynamisch gelinkte applicaties sneller kunnen opstarten. Ze vormen wel geen beveiliging tegen reverse engineering aangezien de adressen toch nog dynamisch berekend worden indien een bepaalde bibliotheek veranderd is. Slinky is een systeem voorgesteld door Collberg et al. dat de voordelen van statisch en dynamisch linken met elkaar combineert [24]. Alle uitvoerbare bestanden zijn volledig statisch gelinkt, maar gemeenschappelijke delen worden op de schijf en in het geheugen gedeeld. Dit gebeurt door voor elke codepagina een digest te genereren die deze pagina uniek identificeert. Aan de hand van deze digest wordt bij het installeren van een nieuwe applicatie gekeken of 17

27 deze codepagina reeds op het systeem aanwezig is, en bij het opstarten van de applicatie of de codepagina al in het geheugen geladen is. Aangezien de applicatie volledig statisch gelinkt is, is het beveiligingsprobleem dat deze scriptie poogt op te lossen ook verdwenen. Slinky is echter enkel een oplossing op Linux. Volledig statisch gelinkte applicaties zijn namelijk niet compatibel met alle versies van Windows wegens de instabiele kernel-interface. Daarnaast vereist Slinky ook een aantal aanpassingen in de kernel, iets wat in het geval van Windows om duidelijke redenen niet mogelijk is in deze scriptie. Er bestaan een aantal tools voor Windows zoals PEBundle [25], MoleBox [26] en DLL- Packager [27] die simpelweg de dynamische bibliotheken waarvan het uitvoerbaar bestand afhankelijk is samen met dit bestand mee inpakken. Er wordt dan nog extra code aan het uitvoerbaar bestand toegevoegd om dynamisch deze bibliotheken weer uit te pakken en de nodige symbolen op te zoeken. De resulterende applicatie is niet echt statisch gelinkt en hoewel ze minder meta-informatie bevat is ze nog steeds vatbaar voor API-hooking. Deze oplossingen zullen ook nooit de de systeembibliotheken aan het uitvoerbaar bestand toevoegen, en de interface tussen de systeembibliotheken en de rest van de applicatie zal dus blijven bestaan. 2.5 Het PE-formaat Windows gebruikt voor uitvoerbare bestanden het PE-formaat, waarbij de PE staat voor Portable Executable. In deze sectie worden een aantal eigenschappen van het PE-formaat uitgelegd die van belang zijn in deze scriptie. Net zoals objectbestanden bestaat een bestand van dit formaat uit headers die de rest van het bestand beschrijven en uit een aantal secties. De secties die gebruikt worden, zijn doorgaans dezelfde als diegene die in objectbestanden gebruikt worden (met dezelfde eigenschappen). Er zijn ook een aantal extra mogelijke secties zoals.edata (voor geëxporteerde symbolen),.idata (voor geïmporteerde symbolen) en.reloc. Voor meer informatie dan in deze sectie gegeven wordt, zie de Microsoft PE/COFF Specification [28] Dynamisch linken Het PE-formaat biedt ondersteuning voor dynamisch linken. Het formaat wordt namelijk niet enkel gebruikt voor uitvoerbare bestanden (exe s) maar ook voor dynamische bibliotheken (Dynamic-Link Libraries of DLL s). Een PE-bestand kan symbolen exporteren en importeren, het exporteert symbolen die in het bestand gedefinieerd zijn zodat andere bestanden ze kunnen gebruiken, en importeert symbolen uit andere PE-bestanden die deze exporteren. Zowel uitvoerbare bestanden als DLL s importeren meestal symbolen, maar enkel DLL s exporteren doorgaans symbolen. De meta-informatie aanwezig in het formaat die het mogelijk maakt om dynamisch te linken vinden we in de export- en importtabellen. De exporttabellen bevatten de symbolen die de DLL exporteert met hun adres relatief t.o.v. de base (dit adres noemen we een Relative Virtual Address, of RVA). De base (of het basisadres) van een PE-bestand is het adres waarop het in het geheugen geladen wordt. Dit adres is niet altijd hetzelfde. De importtabellen bevatten 18

28 Figuur 2.7: Een voorbeeld van de importtabellen van een PE-bestand. Figuur 2.8: Een voorbeeld van de exporttabellen van een PE-bestand. de namen van de DLL s waaruit er symbolen geïmporteerd worden (de exporterende DLL), en per geïmporteerde DLL is er een lijst van symbolen die er uit geïmporteerd worden. Een deel van de importtabellen valt te zien in het voorbeeld op Figuur 2.7. Veel van de voor deze uitleg niet relevante velden zijn niet aanwezig op de figuur. Per geïmporteerde DLL is er een Import Descriptor aanwezig in de tabellen. In het voorbeeld wordt enkel de Import Descriptor voor user32.dll getoond. De Import Lookup Table (of ILT ) bestaat uit RVA s naar de informatie die we nodig hebben om symbolen te importeren. De uit user32 geïmporteerde symbolen zijn GetMessage, LoadIcon en TranslateMessage. Op de figuur is ook de Import Address Table (of IAT ) aanwezig, waarvan we het nut in Sectie wordt uitgelegd. Het importeren van een symbool kan op twee manieren: via naam (zoals in het voorbeeld) of via ordinaal. Indien een symbool geïmporteerd wordt via naam wordt deze naam in de importtabellen bijgehouden. Om het adres van een symbool te berekenen wordt deze naam opgezocht binnen de Export Name Table of ENT van de juiste DLL. Deze tabel bevat een alfabetisch gesorteerde lijst van geëxporteerde symboolnamen. Eens deze naam gevonden is, wordt de index ervan binnen de ENT gebruikt als een index in de ordinaaltabel. Op deze index in de ordinaaltabel vinden we dan de ordinaal die gebruikt wordt als index in de Export Address Table of EAT. Deze tabel bestaat uit een reeks RVA s (t.o.v. het basisadres van de exporterende DLL), één voor elk geëxporteerd symbool. De gevonden RVA, opgeteld met het basisadres van de exporterende DLL levert het symbooladres. Een voorbeeld van een deel van de exporttabellen valt te zien op Figuur 2.8. De procedure om het adres van het symbool LoadIcon te berekenen wordt hier voorgesteld a.d.h.v. de rode genummerde pijlen. 19

29 Figuur 2.9: Een voorbeeld van een dynamisch gelinkt PE-bestand. Bij import via ordinaal dient de ordinaal (die in de importtabellen bijgehouden wordt) direct als index in de EAT. Op deze manier wordt het symbooladres dus iets sneller gevonden. Als er echter een nieuwe versie van de DLL gemaakt wordt, kan het zijn dat de index van het symbool in de EAT verandert. Import via ordinaal is dus niet even toekomstbestendig als import via naam en wordt nauwelijks gebruikt (voornamelijk in de systeembibliotheken). Een andere eigenschap van het PE-formaat die quasi enkel in de systeembibliotheken gebruikt wordt is export forwarding (of export-doorverwijzing). Als een DLL een export doorverwijst wil dit zeggen dat het symbool wel geëxporteerd wordt door de DLL, maar niet echt aanwezig is in de DLL. Het symbool is een alias voor een ander symbool in een andere DLL, en de informatie om dit symbool in de andere DLL op te zoeken is aanwezig in de eerste DLL in plaats van het symbool zelf. Deze informatie vind men dan in een string van de vorm DLLNAAM.FunctieNaam. Het door kernel32 geëxporteerde symbool HeapAlloc wordt bijvoorbeeld doorverwezen naar NTDLL.RtlAllocateHeap Laden PE-bestanden worden in het geheugen geladen door de loader, die deel uitmaakt van het besturingssysteem. Niet alleen het PE-bestand zelf maar ook de DLL s waaruit het symbolen importeert, worden in het geheugen geladen en de adressen van de geïmporteerde symbolen worden berekend. De geïmporteerde DLL s kunnen natuurlijk zelf ook symbolen importeren zodat nog andere DLL s waarvan zij afhankelijk zijn ook in het geheugen geladen zullen worden, enzoverder. Eens een PE-bestand geladen is wordt het beginpunt (indien aanwezig) aangeroepen. Bij een uitvoerbaar bestand is dit het begin van de uitvoering, bij een DLL is dit een initialisatieroutine. De adressen van de geïmporteerde symbolen worden bij het laden van het PE-bestand gevonden en weggeschreven in de IAT (zie Figuur 2.7). De IAT bevatte van tevoren dezelfde RVA s als de ILT (zie Sectie 2.5.1). Deze worden dus overschreven met de eigenlijke adressen van de symbolen. Alle instructies die gebruik maken van een geïmporteerd symbool hebben als één van hun operanden een locatie in de IAT (zie als voorbeeld Figuur 2.9). Een operand kan op 20

30 indirecte wijze gebruikt worden. Het operand zelf wordt dan niet als een waarde beschouwd, maar als het adres van een waarde. Het is deze waarde die door de instructie gebruikt wordt. Alle instructies die een geïmporteerd symbool gebruiken, maken dus indirect gebruik van een operand. De IAT is een veelgebruikte vector voor aanvallen. De adressen van geïmporteerde functies kunnen namelijk gemakkelijk overschreven worden. Deze techniek staat bekend als IAThooking, wat een variatie is op API-hooking [29]. Het adres van de echte geïmporteerde functie in de IAT wordt overschreven met het adres van een door een aanvaller geschreven functie. Het overschrijven gebeurt door geïnjecteerde code (bv. via DLL injection [30]) of vanuit een ander proces Rebasing Een laatste eigenschap van het PE-formaat die we moeten aanhalen, is dat bestanden in het formaat rebaseable zijn. PE-bestanden bevatten absolute geheugenadressen die berekend zijn met de veronderstelling dat het bestand op een specifiek adres in het geheugen geladen wordt (de base, of het basisadres). Deze absolute adressen worden onder meer gebruikt om naar data op een bepaald adres te refereren. Bij een uitvoerbaar bestand kan ervan uitgegaan worden dat het basisadres waarop het bestand berekend is ook datgene is waarop het geladen wordt (meestal 0x400000). Bij een DLL is dit niet per se het geval. Het is gemakkelijk mogelijk dat in één van de adresruimtes van de applicaties waarin de DLL gebruikt wordt het basisadres reeds gebruikt wordt door een andere DLL. In dit geval moeten alle absolute adressen in de DLL herberekend worden. Dit proces heet rebasing. Om dit te kunnen doen wordt er een lijst met RVA s voor de locaties van alle absolute adressen binnen het bestand bijgehouden in de.reloc-sectie (zogenaamde base relocaties). In het voorbeeld op Figuur 2.10 maakt een inc-instructie (gelegen in de.text-sectie) gebruik van een statisch gealloceerde variabele (gelegen in de.data-sectie). De DLL is berekend op 0x als basisadres. De inc-instructie maakt gebruik van een absoluut adres voor de variabele (0x ) voor rebasing), en er is een base relocatie die naar het adres van dit absoluut adres wijst. Indien het adres 0x bezet is en de daarom op basisadres 0x geladen wordt, moet er aan rebasing gedaan worden. Het absoluut adres van de variabele wordt dan herberekend (als 0x ) en het oude adres in de inc-instructie wordt overschreven. DLL s kunnen na rebasing op eender welk geheugenadres geladen worden. De mogelijkheid om een component (ook uitvoerbare bestanden) op eender welk geheugenadres te laden heeft ook een voordeel op beveiligingsvlak. Als namelijk de adresruimte van een proces willekeurig ingedeeld is dan wordt het voor een aanvaller moeilijker om een exploit te schrijven die het proces op een effectieve manier aanvalt [31][32]. Met een willekeurige indeling willen we zeggen dat de DLL s en het uitvoerbaar bestand op een willekeurig basisadres geladen worden voor elke instantie van de applicatie. We noemen deze techniek Address Space Layout Randomization of ASLR en base relocaties maken deze techniek mogelijk op Windows [33]. 21

31 Figuur 2.10: Een voorbeeld van rebasing. Om op andere platformen zoals Linux (waarop ASLR ook gebruik wordt) het laden van een component op een willekeurig geheugenadres toe te laten wordt er gebruik gemaakt van Position Independent Code of PIC [2]. Door een extra indirectie toe te voegen kunnen uitvoerbare bestanden en dynamische bibliotheken daar op eender welk geheugenadres geladen worden zonder dat er een extra proces zoals rebasing aan te pas komt. De code voert zonder probleem uit op elk adres, maar presteert iets slechter vanwege de indirectie. 2.6 De Windows-systeembibliotheken De systeembibliotheken zijn een onderdeel van het Windows-besturingssysteem en verschillen qua inhoud (en soms ook qua structuur) tussen de verschillende versies. Ze bieden wel een stabiele interface aan voor gebruik door applicaties, maar weinig van wat zich achter deze interface bevindt is officieel gedocumenteerd en/of gegarandeerd stabiel. We zullen kort de structuur en verschillende interfaces van de systeembibliotheken bespreken. Hierbij baseren we ons op Windows 8/8.1. De belangrijkste systeembibliotheken met hun onderlinge afhankelijkheden zijn te zien op Figuur Een bibliotheek is afhankelijk van een andere bibliotheek als ze symbolen importeert uit de andere bibliotheek. Dit wordt aangeduid met een pijl van de eerste bibliotheek naar de tweede De verschillende API s In de eerste versie van Windows NT waren er subsystemen aanwezig voor drie gebruiksomgevingen: Windows, POSIX en OS/2. Dit gebruik van subsystemen maakte het mogelijk om applicaties die bedoeld zijn voor verschillende gebruiksomgevingen op eenzelfde besturingssysteem uit te voeren. Hoewel er nog altijd een subsysteem voor Unix-gebaseerde applicaties (SUA) bestaat is het Windows-subsysteem overduidelijk het belangrijkste. Bepaalde functionaliteit is enkel in het Windows-subsysteem geïmplementeerd zodat andere subsystemen deze enkel kunnen aanroepen via het Windows-subsysteem, en quasi alle applicaties voor het 22

32 Figuur 2.11: De belangrijkste Windows-systeembibliotheken met onderlinge afhankelijkheden. Windows-besturingssysteem worden voor dit subsysteem geschreven. De API aangeboden door dit subsysteem staat bekend als de Windows API (specifiek voor 32-bit applicaties de Win32 API ), en is goed gedocumenteerd [33]. De symbolen geëxporteerd door kernel32, user32 en gdi32 zijn een onderdeel van de Windows API. Naast deze DLL s zijn er nog veel meer (minder belangrijke) systeembibliotheken wiens interfaces deel zijn van de Windows API. kernel32 biedt functionaliteit aan om gebruik te maken van typische kerneldiensten die te maken hebben met het bestandssysteem, het beheren van processen en threads, geheugenbeheer et cetera. Het manipuleren van de Windows gebruikersinterface (i.e. van menu s, vensters e.d.) gebeurt via user32, terwijl gdi32 functionaliteit aanbiedt om uitvoer te genereren op grafische hardware (bv. een lijn tekenen). Op een lager niveau vinden we de grotendeels ongedocumenteerde Native API [33][34][35]. Deze wordt gebruikt door de verschillende subsystemen om de kernel aan te spreken, en door zogenaamde native applicaties die niet binnen een subsysteem uitvoeren (zoals bv. drivers). De Native API kan aangeroepen worden vanuit zowel kernel- als user-modus. In kernel-modus bestaat deze uit functies geëxporteerd door ntoskrnl.exe (de kernel-image), in user-modus uit gelijknamige door ntdll geëxporteerde functies die eenvoudige wrappers zijn rond systeemroepen naar de eigenlijke functies (geïmplementeerd in de kernel). Naast de Native API bevat ntdll loaderfunctionaliteit en algemene functionaliteit die door de subsystemen gebruikt wordt zoals een aantal functies uit de C-standaardbibliotheek en functies die communicatie tussen de subsystemen mogelijk maakt. Aangezien ntdll zich architecturaal net boven de kernel bevindt, importeert ze geen symbolen. Communicatie met de kernel verloopt 23

33 Figuur 2.12: Een aantal voorbeelden van het API-set-schema. via systeemoproepen Het API-set-schema Bij de introductie van Windows 7 en Windows 8 vond er een heuse reorganisatie van de systeembibliotheken plaats. Omdat de door de applicaties gebruikte API stabiel moet blijven is dit allemaal onder de oppervlakte gebeurd, en is dit niet echt door Microsoft gedocumenteerd. Er werd functionaliteit verplaatst tussen DLL s, er kwamen DLL s bij (zoals KernelBase, die functionaliteit bevat die eerder in kernel32 zat), en het API-set-schema werd geïntroduceerd [36][37][38][39][40]. Het API-set-schema is een mechanisme dat voor een ontkoppeling zorgt tussen de plaats waar een API gedefinieerd wordt en de plaats waar deze geïmplementeerd wordt. Er wordt gebruik gemaakt van API-sets, zogenaamde groepen van geëxporteerde functies met een gemeenschappelijke functionaliteit (bv. alle functionaliteit die met tijd en data te maken heeft). Voor elke API-set bestaat er een virtuele DLL die de functies waaruit de set bestaat exporteert. Deze virtuele DLL s hebben een naam die altijd begint met api- (bv. apims-win-core-datetime-l1-1-0 ). Deze virtuele DLL s bestaan niet echt, en a.d.h.v. het APIset-schema wordt er dynamisch bepaald in welke DLL de eigenlijke implementatie van alle functies uit de API-set aanwezig is (de implementatie-dll of logische DLL). Het API-setschema zelf is aanwezig in een sectie van ApiSetSchema.dll,.apiset genaamd. In Figuur 2.12 links valt een voorbeeld te zien van een DLL die importeert uit api-ms-win-core-datetimel1-1-0, waarvan de bijhorende logische DLL kernel32 is. De echte DLL s worden voorgesteld met rechthoeken, de virtuele met ruiten. Een gestreepte pijl duidt het gebruik van het APIset-schema aan, een volle pijl de feitelijke afhankelijkheid die daaruit volgt. Er is echter een uitzondering. In het geval dat DLL importeert uit een virtuele DLL waarvoor de normale logische DLL dezelfde is als de importerende DLL, bevindt de implementatie zich niet in de normale logische DLL maar in een andere DLL. Zo is er bijvoorbeeld de APIset api-ms-win-core-file-l1-1-0.dll waarvoor kernel32 normaliter de logische DLL is. Indien kernel32 zelf echter uit deze API-set importeert, is de bijhorende logische DLL KernelBase. Deze twee voorbeelden zijn ook te zien op Figuur

34 Het gebruik van het API-set-schema (door te importeren uit virtuele DLL s) gebeurt doorgaans enkel door DLL s van Microsoft-makelij (de systeembibliotheken en anderen die hierop bouwen). 2.7 De kernel-interface in Windows De interface die de kernel aan applicaties aanbiedt noemen we de kernel-interface. Naast deze interface biedt de kernel natuurlijk ook nog interfaces aan voor gebruik door andere componenten uit de kernel-modus (zoals drivers), maar deze zijn niet van belang voor deze scriptie. Net zoals een bibliotheekinterface bestaat uit geëxporteerde symbolen, bestaat de kernel-interface uit de systeemoproepen die mogelijk zijn Systeemoproepen Als een applicatie een geprivilegieerde actie wil ondernemen, moet deze aan de kernel vragen dit voor haar te doen. Dit gebeurt via een systeemoproep. De systeembibliotheken bieden simpele wrapper-functies aan als abstractie voor systeemoproepen. We noemen deze System Call Wrappers of SCW s. We nemen als voorbeeld van een geprivilegieerde actie het alloceren van meer virtueel geheugen. In dit voorbeeld is de naam van de gebruikte SCW NtAllocate- VirtualMemory. Het aanroepen van een SCW (en dus het uitvoeren van een systeemoproep) leidt ertoe dat er in de kernel-modus een functie zal opgeroepen worden om de gevraagde actie te ondernemen. Deze opgeroepen functie noemen we de system service [41][42]. System services hebben dezelfde namen als de SCW s die hun user-modus abstractie vormen, de in het voorbeeld opgeroepen system service heet dus ook NtAllocateVirtualMemory. Aangezien kernel en applicatie in verschillende modi uitvoeren, moet er bij een systeemoproep van modus gewisseld worden. In vroegere tijden gebeurde dit op x86 d.m.v. een interruptinstructie, maar Intel en AMD hebben voor dit doeleind allebei een gespecialiseerde instructie ontwikkeld (respectievelijk sysenter en syscall) die gebruikt wordt op modernere versies van Windows [33]. Welke manier er ook gebruikt wordt om van modus te wisselen, op een zeker moment wordt de routine KiFastCallEntry in kernel-modus opgeroepen [43][44]. Deze routine handelt de systeemoproep af door te beslissen welke system service er gevraagd is, en deze uit te voeren. Om ervoor te zorgen dat KiFastCallEntry kan beslissen welke system service er exact gevraagd wordt, wordt er net voor het uitvoeren van een systeemoproep een waarde in het eax-register geplaatst (de System Call Ordinal of SCO). Dit is een 32-bits waarde, maar niet al deze bits worden echt gebruikt. Figuur 2.13 toont de indeling van de bits in de SCO. Om uit te kunnen leggen hoe een systeemoproep afgehandeld wordt (en hoe de SCO hierbij van pas komt), leggen we eerst een aantal kernel-structuren uit. Een System Service Dispatch Table of SSDT is een tabel bestaande uit adressen van system services. De System Service Number of SSN (zie Figuur 2.13) wordt gebruikt als 12-bits index in deze tabel om de gevraagde system service op te roepen [45][46]. Er zijn minstens twee SSDT s aanwezig in de kernel: één voor gewone system services en één voor grafische system 25

35 Figuur 2.13: De indeling van de SCO. Figuur 2.14: De verschillende structuren die gebruikt worden bij het afhandelen van een systeemoproep. services. Deze laatste SSDT noemen we de Shadow SSDT, en de bijhorende system services zijn niet geïmplementeerd in de kernel-image maar in win32k.sys. Daarnaast is elke thread geassocieerd aan een Service Descriptor Table of SDT. Deze bestaan uit (maximaal) vier System Service Tables of SST s. Een SST bestaat uit het adres van een SSDT en wat gerelateerde informatie (onder meer over de argumenten voor elke system service). Op Figuur 2.14 wordt een beeld van al deze structuren weergegeven. Er zijn slechts twee mogelijke SDT s: KeServiceDescriptorTable en KeServiceDescriptorTableShadow. De eerste wordt gebruikt door gewone threads (systeemthreads), de tweede door threads die grafische functionaliteit gebruiken (GUI-threads). Van zodra een systeemthread probeert grafische functionaliteit te gebruiken, wordt deze omgezet naar een GUI-thread en wordt de KeServiceDescriptorTableShadow zijn SDT. KeServiceDescriptorTable heeft slechts één SST, deze is voor de gewone SSDT. KeServiceDescriptorTableShadow heeft er twee: één voor de gewone SSDT en één voor de Shadow-SSDT. De keuze voor een specifieke SST (en dus SSDT) gebeurt a.d.h.v. een index van 2 bits in de SCO (de SST-index, zie Figuur 2.13). Samengevat kunnen we zeggen dat de SDT thread-afhankelijk is, de SST bepaald wordt a.d.h.v. de SDT en de SST-index, en de system service opgeroepen wordt op basis van de SST en de SSN. 26

36 2.7.2 Syscall en sysenter Er bestaan twee gespecialiseerde instructies om op een x86-processor een systeemoproep uit te voeren. Indien de processor in 32-bits modus uitvoert, moet de sysenter-instructie uitgevoerd indien het om een Intel-processor gaat, en de syscall-instructie indien het om een AMD-processor gaat (deze ondersteunen elkaars instructies niet). Deze instructies hebben een gelijkaardige werking maar verschillen enigszins en zijn niet zomaar verwisselbaar. Alvorens sysenter uit te voeren moet het adres van de top van de stapel opgeslagen worden (dit gebeurt in het edx-register). Bij de syscall-instructie is dit niet nodig [47][33]. Uit compatibiliteitsoverwegingen maken de systeembibliotheken geen direct gebruik van deze instructies. In plaats daarvan bevatten de SCW s een indirecte oproep naar een kleine routine die door de kernel wordt ingesteld bij het opstarten: SystemCallStub. SystemCallStub zal de juiste instructie bevatten om een systeemoproep uit te voeren, en indien nodig het adres van de top van de stapel in het edx-register plaatsen. In het algemeen ziet een van deze indirectie gebruik makende SCW er als volgt uit: mov mov call ret eax, SCO edx, offset SharedUserData!SystemCallStub dword ptr [edx] In 64-bits modus ondersteunen Intel-processors de syscall-instructie wel. Alle systeemoproepen vanuit 64-bits modus gebeuren dan ook via syscall, zonder indirectie: mov syscall ret eax, SCO Instabiliteit Zoals vermeld in de inleiding is de interface aangeboden door de Windows-kernel niet stabiel over verschillende versies. Het probleem is niet dat de system services die aangeboden worden en de argumenten die deze gebruiken veranderen. Deze zijn inderdaad niet gegarandeerd om hetzelfde te blijven, maar in de praktijk veranderen ze nauwelijks. De SCO verbonden aan een specifieke system service daarentegen verandert wel tussen verschillende versies van Windows. Deze kan zelfs veranderen bij het uitbrengen van een nieuwe service pack, en de SCO s voor dezelfde system services verschillen bv. ook tussen Windows 8 en Windows 8.1. Een tabel met SCO s voor alle systeemoproepen op alle recente versies van Windows kan online gevonden worden [48]. Om een volledig statisch gelinkte applicatie compatibel te maken met verschillende versies van Windows is het dus voornamelijk van belang om ervoor te zorgen dat de applicatie op elke versie de gepaste SCO s gebruikt. 27

37 Figuur 2.15: De architectuur van de WoW64-laag Systeemoproepen en systeembibliotheken Er zijn een aantal systeembibliotheken die SCW s bevatten. Zo is er ntdll dat de Native API bevat (zie Sectie 2.6.1). Deze API bestaat uit geëxporteerde SCW s waarvan de namen allemaal beginnen met een Nt zoals NtAllocateVirtualMemory, NtWritefile en NtCreateProcess. Deze SCW s vormen een abstractie voor de gelijknamige system services, allen geïmplementeerd in de kernel-image. De adressen van deze system services zijn te vinden in de gewone SSDT, en de SCO voor deze systeemoproepen bevat dus als SST-index altijd 0. Daarnaast zijn er ook (voornamelijk ongeëxporteerde) SCW s in user32 (namen beginnende met NtUser ) en gdi32 (namen beginnende met NtGdi ). De bijhorende system services zijn geïmplementeerd in win32k.sys en hun adressen zijn te vinden in de Shadow SSDT. Bijgevolg bevat de SCO voor deze systeemoproepen altijd een 1 als SST-index WoW64 WoW64 is de afkorting voor Win32 on Windows 64-bit, de emulator die het mogelijk maakt om Win32-applicaties (bedoeld voor een 32-bits Windows) uit te voeren op een 64-bits Windows [49]. Deze emulator is eigenlijk een laag tussen de 32-bits applicatie en het 64-bits besturingssysteem, bestaande uit drie DLL s: wow64, wow64cpu en wow64win [50]. In de adresruimte van elke 32-bits applicatie zijn dus naast de 32-bits systeembibliotheken ook nog de 64-bits WoW64-bibliotheken en een 64-bits versie van ntdll aanwezig, hoewel de applicatie van deze laatste twee geen weet heeft (zie Figuur 2.15). De 32-bits systeembibliotheken op een 64-bits Windows zijn zeer gelijkaardig aan die van een 32-bits Windows, maar er is een belangrijk verschil: ze doen zelf geen systeemoproepen [51]. Als we een 32-bits systeembibliotheek op een 64-bits Windows 8/8.1 beschouwen, dan ziet een SCW er als volgt uit (vergelijk met Sectie 2.7.2): mov call ret eax, SCO large dword ptr fs:0xc0 De SCO ziet er in dit geval ook net iets anders uit (zie Figuur 2.16). De bovenste 16 bits vormen een index die gebruikt wordt door de WoW64-laag (de WoW64-index), en er schieten 28

38 Figuur 2.16: De indeling van de SCO voor WoW64. nog maar twee bits over die ongebruikt zijn (aangeduid met ONG. ). De indirecte call-instructie die de sysenter- of syscall-instructie vervangt in de 32-bits systeembibliotheken heeft als doeladres een far jump -instructie in wow64cpu. Dit soort instructie springt naar een specifiek adres in een specifiek segment. In dit geval springt de instructie naar de functie CpupReturnFromSimulatedCode binnen wow64cpu, in een 64-bits segment. Dit is dus het punt waarop de CPU overschakelt naar 64-bits modus. Alvorens de syscallinstructie uit te voeren, moeten de argumenten (die nu op een 32-bits stapel staan) aangepast worden om correct gebruikt te worden door de 64-bits kernel. De exacte manier waarop dit gebeurt, hangt af van de WoW64-index. Eens de systeemoproep uitgevoerd is, wordt het resultaat aangepast tot hetgeen een 32-bits kernel zou hebben teruggeven. Hierna wordt er terug overgeschakeld naar 32-bits modus en wordt de WoW64-laag verlaten. De gebruikte SCO wordt niet aangepast door de WoW64-laag. Dit impliceert dat op een 64-bits Windows de SCO s die de 32-bits en 64-bits systeembibliotheken gebruiken voor een specifieke system service dezelfde zijn. De SCO s die de 32-bits systeembibliotheken op een 32-bits en een 64-bits Windows gebruiken verschillen wel. 29

39 Hoofdstuk 3 Encrypteren van meta-informatie In dit hoofdstuk wordt de methode voorgesteld die door het encrypteren van meta-informatie als doel heeft om de interfaces tussen een uitvoerbaar bestand en alle gebruikte bibliotheken te verbergen. Dit is voordelig op vlak van beveiliging. De meta-informatie aanwezig in dynamisch gelinkte uitvoerbare bestanden kan namelijk gebruikt worden bij het statisch analyseren van de applicatie. In de besproken methode wordt de meta-informatie in geëncrypteerde vorm opgeslagen zodat dynamisch linken nog mogelijk blijft, maar statische analyse sterk bemoeilijkt wordt. Eerst wordt de algemene werking besproken, vervolgens wordt de methode in meer detail uitgewerkt en tot slot komen de beperkingen en mogelijke uitbreidingen van de methode aan bod. 3.1 De algemene werking Het doel van de methode is om op basis van het oorspronkelijk uitvoerbaar bestand door Diablo een herschreven bestand te laten genereren waarin de meta-informatie in geëncrypteerde vorm is opgeslagen. Aan de hand van deze geëncrypteerde meta-informatie zal de applicatie tijdens het uitvoeren de benodigde symbolen vinden (op het moment dat ze nodig zijn). De meta-informatie wordt niet simpelweg dynamisch gedecrypteerd naar zijn oorspronkelijke vorm, deze zou namelijk bij het uitvoeren van de applicatie gemakkelijk uit het geheugen gehaald kunnen worden om vervolgens te gebruiken in een statische analyse. In plaats daarvan worden de geïmporteerde symbolen gevonden op basis van de geëncrypteerde metainformatie, zonder deze te decrypteren. Om een herschreven bestand te genereren dat hiertoe in staat is, maakt Diablo twee grote aanpassingen aan het uitvoerbaar bestand. Ten eerste worden de importtabellen (die de meta-informatie bevatten) uit het oorspronkelijke bestand verwijderd en in geëncrypteerde vorm toegevoegd aan het nieuwe bestand. Ten tweede wordt er extra code aan het bestand toegevoegd. Deze code de zogenaamde glue code staat in voor het dynamisch vinden van de benodigde symbolen op basis van de geëncrypteerde meta-informatie. De glue code bevat naast een aantal hulpfuncties twee hoofdfuncties. De eerste is de initialisatiefunctie die het nieuwe beginpunt van de applicatie wordt. Deze initialiseert een aantal variabelen die door de rest van de glue code gebruikt worden, waarna ze naar het oorspronkelijke beginpunt van de applicatie springt. Daarnaast is er ook de laadfunctie die instaat voor het dynamisch opzoeken van de geïmporteerde symbolen op basis van de geëncrypteerde 30

40 Figuur 3.1: De algemene werking van de methode. meta-informatie. Diablo vervangt elke instructie die gebruik maakt van geïmporteerde symbolen (dit is een indirecte instructie die gebruik maakt van de IAT, zie Sectie 2.5.2) door een oproep naar de laadfunctie. Eens de laadfunctie opgeroepen zal deze de instructie (die nu een call-instructie is) terug herschrijven naar de instructie die er eigenlijk moet staan, namelijk de directe variant van de (indirecte) oorspronkelijke instructie. De instructie die er eigenlijk moet staan noemen we de eigenlijke instructie. De algemene werking wordt nog eens voorgesteld op Figuur 3.1. Deze figuur toont ook een voorbeeld van het controleverloop van de oorspronkelijke en de herschreven applicatie, voorgesteld door de nummering. 3.2 Het encrypteren van de meta-informatie Voor het encrypteren wordt er gebruik gemaakt van eenrichtingsfuncties. Dit zijn functies waarvan de uitvoer gemakkelijk te berekenen is gegeven de invoer, maar waarvoor het zeer moeilijk is de invoer terug te vinden gegeven de uitvoer. Het is deze uitvoer die bijgehouden wordt in het herschreven bestand en gebruikt zal worden om toch nog de geïmporteerde symbolen te kunnen vinden. De specifieke vorm van eenrichtingsfuncties die in de implementatie gebruikt wordt is die van een hashfunctie, met als uitvoer een hashwaarde. De informatie die we zeker nodig hebben om dynamisch geïmporteerde symbolen te kunnen vinden bestaat uit de namen van de DLL s waaruit we symbolen importeren en de namen (of ordinalen) van deze symbolen zelf. In de huidige implementatie is er enkel ondersteuning voor import via naam en niet via ordinaal, omdat er niet veel uitvoerbare bestanden zijn die nog van het laatste gebruik maken. Zo n uitvoerbare bestanden bestaan echter wel en om alle uitvoerbare bestanden te kunnen herschrijven zou ook ondersteuning voor import via ordinaal voorzien moeten worden. Er wordt in de glue code een tabel voorzien die de hash bevat voor de naam van elke gebruikte DLL, zodat de glue code deze kan laden. Deze tabel noemen we de DLL-tabel. 31

41 Figuur 3.2: De structuur van een element in de DYNIMP-tabel. De groottes van de velden zijn niet op schaal. Om elke oproep naar de laadfunctie te kunnen herschrijven naar de eigenlijke instructie wordt er ook een tabel voorzien de DYNIMP-tabel die een element bevat voor elke instructie die een geïmporteerd symbool gebruikt. Dit element bevat alle informatie die nodig is voor het herschrijven. Figuur 3.2 toont de structuur van dit element. De hash van het terugkeeradres en de salt worden gebruikt door de laadfunctie om te identificeren welk element uit de DYNIMPtabel ze moet gebruiken. De hash van de symboolnaam en de index in de DLL-tabel worden gebruikt om het symbooladres dynamisch te berekenen, en alle andere velden worden gebruikt om de call laadfunctie -instructie te herschrijven. De laadfunctie moet als ze aangeroepen wordt in staat zijn te identificeren welk element uit de tabel te gebruiken. Een mogelijkheid zou zijn om Diablo net voor de oproep naar de laadfunctie een instructie te laten toevoegen die een bepaalde waarde in een register plaatst op basis waarvan deze identificatie kan gebeuren. We verkiezen echter zo weinig mogelijk aanpassingen in de oorspronkelijke code aan te laten brengen door Diablo, omdat we bij het dynamisch herschrijven deze aanpassingen weer ongedaan moeten maken. De identificatie gebeurt daarom op basis van het terugkeeradres, dat bij een functieoproep automatisch op de stapel geplaatst wordt. Als we de terugkeeradressen rechtstreeks in de tabel zouden opslaan, zou het mogelijk zijn om gewoon door naar de tabel te kijken af te leiden op welke locaties in de code er geïmporteerde symbolen gebruikt worden. Om dit ietwat te bemoeilijken zijn ook de terugkeeradressen geëncrypteerd d.m.v. een eenrichtingsfunctie. Aangezien we met 32-bits adressen werken en de uitvoerwaarden ook een grootte van 32 bits hebben, zijn de invoerruimte en de uitvoerruimte van de functie even groot. Dit is negatief voor de kwaliteit van een eenrichtingsfunctie en daarom wordt er gebruik gemaakt van een salt [52]. Een salt bestaat uit extra willekeurig gegenereerde bytes die aan de invoer toegevoegd worden waardoor de invoerruimte vergroot wordt. De formule voor de oorspronkelijke eenrichtingsfunctie is h(x), met x als invoer en het resultaat van functie als uitvoer (of hash). Indien we gebruik maken van een salt wordt deze formule h(x, r()). Hierbij is r() een functie die geen invoer heeft maar een willekeurige waarde als uitvoer heeft. De uitvoer van deze functie dient als extra invoer voor de eenrichtingsfunctie. Het gebruik van salts maakt het ook mogelijk om, in geval van botsingen tussen de uitvoerwaarden, nieuwe uitvoerwaarden te genereren op basis van dezelfde (echte) invoer, maar met nieuwe salts. 32

42 3.3 De glue code Aanpassingen in Diablo Het toevoegen van de glue code gebeurt in Diablo na het emuleren van het linkerproces, maar voor het disassembleren van de.text-secties en het opbouwen van de ACVG. Op dit punt voegen we de objectbestanden die de glue code bevatten toe aan het parent-object, zodat we veranderingen kunnen maken in de ACVG en verbindingen kunnen maken tussen de oorspronkelijke applicatie en de glue code. Na het opbouwen van de controleverloopgraaf wordt deze door Diablo onderverdeeld in functies. Knopen die niet bereikbaar zijn vanaf de beginknoop worden geen onderdeel van een functie. Indien geen van de BBL s waaruit een functie bestaat bereikbaar is vanuit de beginknoop, zal deze groep BBL s niet als een functie herkend worden door Diablo. Dit is natuurlijk het geval voor de knopen uit de glue code, er zijn namelijk nog geen verbindingen tussen de glue code en de oorspronkelijke code. Bijgevolg zullen de initialisatiefunctie noch de laadfunctie (noch enige hulpfuncties) herkend worden. Omdat het ons voordelig uitkomt als functies als zodanig herkend worden maken we gebruik van de force reachable-vlag die Diablo dwingt een specifiek symbool als bereikbaar te beschouwen, waardoor de verwante functie herkend wordt. Er moeten een aantal veranderingen gebeuren in de controleverloopgraaf om de glue code echt aan de applicatie toe te voegen. Zo moet de initialisatiefunctie het beginpunt worden en op het einde naar het oorspronkelijke beginpunt springen. Ten tweede moet elke instructie die gebruik maakt van geïmporteerde symbolen vervangen worden door een oproep naar de laadfunctie. Deze instructies worden bepaald door alle bestaande relocaties te overlopen en die relocaties te zoeken die van een instructie naar een locatie binnen de IAT wijzen. Voor elke instructie die gebruik maakt van een geïmporteerd symbool wordt er een element aan de DYNIMP-tabel toegevoegd alvorens de instructie te vervangen. Er zijn twee gevallen, afhankelijk van wat voor soort instructie we vervangen. Indien het een controleverloopinstructie is, zal deze zich aan het einde van zijn BBL bevinden. In dit geval vervangen we de uitgaande pijl door een call-pijl met als eindknoop het eerste BBL van de laadfunctie. De oorspronkelijke eindknoop van deze pijl is een helleknoop. Het operand is namelijk een adres dat opgeslagen ligt binnen de IAT, en er is dus sprake van indirect controleverloop. Een voorbeeld waarin de controleverloopinstructie in kwestie een call-instructie is, is voorgesteld in Figuur 3.3. In het tweede geval hebben we te maken met een instructie die geen controleverloopinstructie is, en dus niet noodzakelijk de laatste instructie binnen zijn BBL is. Mochten we deze instructie vervangen door een call naar de laadfunctie dan zou dit resulteren in een call in het midden van een BBL, wat niet toegestaan is. Daarom zullen we in dit geval het BBL net na de instructie opsplitsen in twee BBL s en de nodige aanpassingen maken. Een voorbeeld van dit geval waarin de te vervangen instructie een mov-instructie is, valt eveneens te zien in Figuur

43 Figuur 3.3: Voorbeelden voor het vervangen van instructies die geïmporteerde symbolen gebruiken. Bij het vervangen van de oorspronkelijke instructie door een call-instructie moet er ook rekening gehouden worden met een eventueel verschil in lengte tussen de call-instructie (5 bytes) en de eigenlijke instructie die na het oproepen van de laadfunctie de call-instructie zal vervangen. Indien de eigenlijke instructie langer is dan 5 bytes wordt er extra plaats voorzien door middel van padding bytes (NOP-instructies) De initialisatiefunctie De initialisatiefunctie bootst de initialisatie na die bij het opstarten van een nieuwe applicatie plaatsvindt. De DLL s waarvan de applicatie afhankelijk is, worden in de adresruimte van het proces geladen en hun initialisatieroutines worden uitgevoerd. In tegenstelling tot de normale initialisatie worden de adressen van de geïmporteerde symbolen nog niet door de initialisatiefunctie berekend en op de juiste plaats weggeschreven. Dit zal op een later moment (voor elk afzonderlijk gebruik van een symbool) gebeuren bij het aanroepen van de laadfunctie. Het volledige proces om een DLL te laden is een ingewikkelde taak waarvoor ook medewerking van de kernel vereist is. We kunnen dit volledige proces laten uitvoeren d.m.v. één functie-aanroep, namelijk die van de geëxporteerde functie LoadLibrary[53] uit een van de systeembibliotheken, kernel32. LoadLibrary zal ons het adres teruggeven waarop de DLL is geladen, wat we voor later gebruik zullen bijhouden. Er zijn nog meer plaatsen in de glue code waar het ons voordelig uitkomt om gebruik te maken van de functionaliteit die kernel32 aanbiedt, zoals bijvoorbeeld bij het herschrijven van instructies. Het vinden van de symbolen die de glue code nodig heeft uit kernel32 gebeurt op dezelfde wijze als waarop het vinden van de geïmporteerde symbolen voor de eigenlijke applicatie gebeurt, namelijk op basis van gehashte symboolnamen. Rest wel de vraag hoe we kernel32 kunnen laden als we nog niet beschikken over de functionaliteit om een DLL te 34

44 laden. In feite is kernel32 reeds aanwezig in de adresruimte van het proces. Bij het opstarten van een applicatie zal Windows namelijk een aantal systeembibliotheken automatisch laden, zelfs als de applicatie hieruit geen symbolen importeert (en zelfs als de applicatie in het geheel geen symbolen importeert). Eén van deze systeembibliotheken is kernel32. kernel32 is dus wel degelijk aanwezig in de adresruimte van ons proces, het enige wat ons nog rest is het basisadres ervan te vinden. Dit is een probleem dat men ook tegenkomt bij Windows-shellcodes. Op het moment dat een shellcode aan zijn uitvoering begint, is kernel32 reeds aanwezig in de adresruimte van het aangevallen proces, maar kent de shellcode het adres ervan niet. Aangezien de shellcode de functionaliteit van kernel32 wil gebruiken voor zijn eigen doeleinden is de eerste stap in de uitvoering dus dit adres te vinden. Er bestaat een algemene manier om dit te doen die gebruik maakt van het Process Environment Block (PEB) [54] [55]. Deze methode wordt ook in de initialisatiefunctie gebruikt. Eens de initialisatiefunctie over het adres van kernel32 beschikt worden de adressen berekend van alle symbolen die de glue code hieruit gebruikt. kernel32 exporteert de functie GetProcAddress [56] die gegeven het adres van een DLL en een symboolnaam het adres van het symbool berekent, maar doordat we met hashes werken in plaats van de eigenlijke namen kunnen we deze functie niet gebruiken. Daarom is er in de glue code een functie aanwezig met dezelfde functionaliteit als GetProcAddress, maar dan op basis van de hashwaarde van een symboolnaam. Deze functie overloopt alle namen in de ENT van de exporterende DLL en vergelijkt per naam de resulterende hashwaarde met de hashwaarde van de symboolnaam die we zoeken. Indien deze twee gelijk zijn hebben we het gezochte symbool (en bijhorend adres) gevonden. Het is echter ook mogelijk dat we te maken hebben met een geëxporteerd symbool dat doorverwezen wordt (zie Sectie 2.5.1). In dit geval is het bijhorend adres niet dat van het symbool zelf gezien het niet aanwezig is in de DLL maar het adres van een string van de vorm DLLNAAM.FunctieNaam [28]. We kunnen deze informatie nu gebruiken om de eigenlijke DLL te laden via LoadLibrary als de DLL reeds geladen is zal LoadLibrary gewoon het adres teruggeven zonder de DLL nog eens te laden en vervolgens GetProcAddress gebruiken om het adres te vinden van het symbool waarnaar er doorverwezen wordt. Nu we beschikken over de nodige functionaliteit uit kernel32 kunnen we beginnen de DLL s waarvan de applicatie afhankelijk is te vinden en te laden. Aangezien we weer enkel de gehashte namen hebben en niet de namen zelf, kunnen we niet meteen de functie LoadLibrary gebruiken. Er zijn twee plaatsen van waarop DLL s geladen kunnen worden bij het opstarten van een applicatie: de system32 -map en de map waarin de applicatie zelf aanwezig is. Eerst lopen we door de system32-map en vergelijken per DLL de hash van hun naam met de hash van de gezochte naam. Indien er geen match gevonden wordt doen we hetzelfde bij applicatiemap. Vervolgens gebruiken we de gevonden naam als argument in LoadLibrary en overschrijven in de DLL-tabel de hash van de naam met het adres van de DLL. Op het einde van de initialisatiefunctie springen we naar het oorspronkelijke beginpunt van de applicatie en wordt er aan de uitvoering van de echte applicatie begonnen. 35

45 Figuur 3.4: Voorbeelden van het herschrijven van instructies die geïmporteerde symbolen gebruiken De laadfunctie De laadfunctie zal, eens ze opgeroepen wordt, de call-instructie vanaf waar ze is opgeroepen herschrijven naar de eigenlijke instructie aan de hand van de informatie in de DYNIMP-tabel. Zie Figuur 3.4 voor een aantal voorbeelden hiervan. In het begin van de laadfunctie worden alle caller-saved registers op de stapel geplaatst en deze registers krijgen terug hun oorspronkelijke waarde op het einde van de laadfunctie. Normaal gezien worden deze registers (indien nodig) op de stapel geplaatst net voor een callinstructie. De call laadfunctie -instructie is echter door Diablo aan de applicatie toegevoegd en de oorspronkelijke instructie was niet per se een call-instructie. Daarom zal de laadfunctie voor alle zekerheid de caller-saved registers veilig stellen. De eerste, echte stap is bepalen welk element uit de DYNIMP-tabel benodigd is. Dit gebeurt aan de hand van het terugkeeradres, zoals beschreven in Sectie 3.2. Nadat het juiste element gevonden is, zoeken we (m.b.v. de index in het element) het basisadres op van de DLL waaruit het symbool geïmporteerd wordt. Dit adres wordt samen met de hash van de symboolnaam gebruikt om het adres van het symbool te berekenen. Om de call laadfunctie -instructie te kunnen herschrijven moet eerst het geheugenbereik waarop we willen schrijven schrijfbaar gemaakt worden. Hiervoor gebruiken we de Virtual- Protect [57] functie uit kernel32 die de geheugenbescherming aanpast voor alle geheugenpagina s met minstens één byte in het gevraagde bereik. Het gevraagde geheugenbereik begint op het adres van de call laadfunctie -instructie en heeft de lengte van de instructie waarmee we deze willen vervangen. Deze lengte valt te vinden in het gevonden element uit de tabel en is minstens vijf bytes (minstens één byte opcode en altijd vier voor een adres) en hoogstens vijftien bytes (de maximale lengte van een x86-instructie [47]). Het geheugenbereik wordt leesbaar, schrijfbaar én uitvoerbaar gemaakt. Dit geheugen moet ook uitvoerbaar zijn in het geval dat we een call laadfunctie -instructie willen overschrijven die zich per toeval op eenzelfde pagina bevindt als stukken van de glue code die ook uitgevoerd moeten worden. Nu het geheugen schrijfbaar is kunnen we de eigenlijke instructie wegschrijven en op de juiste plaats binnen de instructie het adres van het symbool dat als operand dient wegschrijven. 36

46 Alle informatie om dit te doen is aanwezig in het element uit de DYNIMP-tabel. Indien de eigenlijke instructie een controleverloopinstructie is (valt te vinden in de tabel) moet niet het adres van het symbool maar een EIP-relatieve offset naar dit adres weggeschreven worden. Eens de instructie aangepast is, wordt VirtualProtect nogmaals opgeroepen om het geheugenbereik weer de oude geheugenbescherming te geven. Omdat zelf-aanpassende code tot problemen met de instructiecaches kan leiden, doen we een oproep naar FlushInstruction- Cache [58]. Uiteindelijk wordt het terugkeeradres van de stapel gehaald, aangepast naar het adres van de herschreven instructie, en terug op de stapel geplaatst. De laadfunctie keert dus terug naar de herschreven instructie zodat de normale uitvoering kan hervatten. Elke call laadfunctie -instructie wordt dus hoogstens één keer uitgevoerd, en het uitvoeren resulteert in het overschrijven van deze instructie met de eigenlijke instructie. Op deze manier wordt de overhead geïntroduceerd door de methode geminimaliseerd. De herschreven instructie maakt ook direct gebruik van het adres van geïmporteerd symbool. Dit in tegenstelling tot de oorspronkelijke, indirecte variant uit de oorspronkelijke applicatie die dit adres uit de IAT haalde. Het verwijderen van deze indirectie heeft een positief effect op de prestatie van de applicatie. 3.4 Beperkingen en mogelijke uitbreidingen De eenrichtingsfuncties Een eerste beperking in de huidige implementatie heeft te maken met het gebruik van eenrichtingsfuncties om de meta-informatie te encrypteren. We vertrouwen erop dat deze functies sterk genoeg zijn zodat het niet mogelijk is om op basis van de uitvoer de invoer af te leiden. De huidige gebruikte eenrichtingsfuncties zijn eerder van functioneel nut dan dat ze cryptografisch sterk zijn. Zelfs indien we gebruik maken van ingewikkeldere eenrichtingsfuncties zal het niet onmogelijk zijn om de invoer te achterhalen aan de hand van de uitvoer doordat de invoerruimte in de praktijk zeer klein is. Er zijn maar een beperkt aantal namen van DLL s die de applicatie kan gebruiken en per DLL is er een beperkt aantal namen van geëxporteerde symbolen. In een normaal gebruiksgeval is het berekenen van eenrichtingsfunctie voor al zijn invoerwaarden een uitdaging die een grote hoeveelheid rekenkracht en tijd vereist. Omdat de feitelijke invoerruimte in dit geval veel kleiner is dan de theoretische invoerruimte bestaande uit alle mogelijke strings kan een aanvaller wel binnen een redelijke termijn voor alle mogelijk invoerwaarden de hashwaarde berekenen. Het zou dus mogelijk zijn voor een aanvaller om alle mogelijk hashwaardes te berekenen, en zo de hashwaardes uit de DYNIMP-tabel en de DLL-tabel te vertalen naar de bijhorende symboolnamen respectievelijk DLL-namen. Het gebruik van salts zou hier ook niet zoveel helpen als men zou verwachten. Stel dat er 3000 DLL s aanwezig zijn in de systeemmap en de applicatiemap tezamen waarvan een applicatie mogelijk gebruik maakt. Als we salts gebruiken moet de aanvaller voor elke gebruikte DLL afzonderlijk de namen van al deze DLL s hashen en vergelijken. Stel dat de applicatie gebruik maakt van 100 DLL s voor het merendeel van de applicaties al een grove overschatting dan komt dit neer op de hashfunctie keer uitvoeren, wat met de rekenkracht van de 37

47 huidige processoren binnen de tijdspanne van enkele seconden gebeurd is. Eens de gebruikte DLL s gekend zijn kan de aanvaller beginnen met de gebruikte symbolen te achterhalen. Deze stap zou via een gelijkaardige procedure gebeuren binnen een gelijkaardig tijdsbestek. Het toevoegen van salts kan wel helpen om van eventuele botsingen tussen de hashwaardes van de DLL-namen en symboolnamen binnen een DLL te voorkomen. Het is dus mogelijk om met enige moeite de meta-informatie toch nog te reconstrueren en aan statische analyse te doen. Een mogelijke uitbreiding om dit te vermijden is om de geëncrypteerde meta-informatie nogmaals te encrypteren d.m.v. white-box cryptografie [59]. De geëncrypteerde meta-informatie zal dan nooit volledig zichtbaar zijn in het geheugen, en deze observeren gaat enkel via dynamische analyse Uitbreiden ondersteuning uitvoerbare bestanden In de huidige implementatie is er nog geen ondersteuning voor uitvoerbare bestanden die aan import via ordinaal doen of die variabelen importeren, omdat dit eigenschappen zijn van het PE-formaat die niet vaak gebruikt worden. Om alle uitvoerbare bestanden te kunnen herschrijven, zouden deze eigenschappen wel ondersteund moeten worden. Lichte aanpassingen in DYNIMP-tabel en de glue code zouden volstaan om ook import via ordinaal te ondersteunen. Momenteel wordt enkel het importeren van functies ondersteund. Het adres van een geïmporteerde functie kan maar in drie instructies gebruikt worden: een call, een jmp, of een mov. In het laatste geval wordt het adres in een register geplaatst voor snellere toegang, wat voordelig is als de functie vaker opgeroepen zal worden. Een geïmporteerde variabele kan echter in zeer veel instructies gebruikt worden: inc, dec, add, sub, mul, imul, div, idiv, or, xor, cmp, et cetera. Voor al deze gevallen zou nog ondersteuning geschreven moeten worden Dynamische aanvallen De applicatie is natuurlijk nog altijd kwetsbaar voor dynamische analyse via hooking. Daarnaast zijn er ook een aantal dynamische aanvallen die het mogelijk maken de meta-informatie te reconstrueren. Als de applicatie lang genoeg aan het uitvoeren is, zullen de adressen van het merendeel van de geïmporteerde symbolen berekend zijn. Een geheugendump van de applicatie op dit moment stelt een aanvaller dus mits enige moeite in staat de symbooladressen te achterhalen uit de herschreven oproepen naar de laadfunctie. Van deze symbooladressen worden dan vervolgens de bijhorende symbolen afgeleid, voor gebruik bij statische analyse. Een mogelijke manier om dit tegen te gaan zou zijn om een mechanisme te implementeren waarbij de instructies die gebruik maken van geïmporteerde symbolen tijdens de uitvoering periodiek terug herschreven worden naar oproepen naar de laadfunctie. In het extreme geval worden deze instructies zelfs nooit herschreven door de laadfunctie. De laadfunctie wordt dan elke keer opgeroepen en zal dan instaan voor het uitvoeren van de benodigde instructie alvorens terug te keren. Dit alles komt de prestatie van de applicatie echter niet ten goede. Het is ook mogelijk voor een aanvaller om de geïmporteerde symbolen te achterhalen zonder 38

48 de applicatie volledig uit te voeren. Door middel van reverse engineering kan het adres van de laadfunctie achterhaald worden, en via statische analyse kunnen alle oproepen naar de laadfunctie (en hun terugkeeradres) gevonden worden. Als een aanvaller eerst de initialisatiefunctie laat uitvoeren en dan de laadfunctie voor elk terugkeeradres laat oproepen, wordt de laadfunctie gebruikt om de geïmporteerde symbolen voor de aanvaller te vinden. Dit vereist natuurlijk wel dat er een aantal aanpassingen aan het uitvoerbaar bestand gebeuren. Om ook de kwetsbaarheid ten opzichte van deze aanvallen (en dynamische analyse) te verminderen, moeten we in het geheel af van het gebruik van dynamische linken en een applicatie creëren die slechts uit één component bestaat. Dit is dan ook wat we zullen doen in Hoofdstuk 4. 39

49 Hoofdstuk 4 Statisch linken Om dynamische analyse tegen te gaan willen we uitvoerbare bestanden zo herschrijven dat ze niet meer afhankelijk zijn van andere componenten (behalve de kernel). In dit hoofdstuk bespreken we de methode van het statisch linken, die exact dat als doel heeft. De herschreven uitvoerbare bestanden zijn slechts compatibel met één versie van Windows, namelijk die versie waarop ze door Diablo gemaakt zijn. Een methode om ze compatibel te maken met meerdere versies van Windows wordt later besproken in Hoofdstuk 5. Eerst worden de verschillende stappen in de methode van het statisch linken overlopen, vervolgens bespreken we partieel statisch linken, en we eindigen met de beperkingen en mogelijke uitbreidingen van de methode. 4.1 Toevoegen van DLL s We willen een herschreven uitvoerbaar bestand creëren dat enkel (rechtstreeks) interageert met de kernel en niet afhankelijk is van DLL s. Aangezien het oorspronkelijk uitvoerbaar bestand natuurlijk wel afhankelijk is van DLL s moeten we een manier vinden om de delen die we nodig hebben uit deze DLL s aan het uitvoerbaar bestand toe te voegen. Een DLL toevoegen gebeurt in Diablo door bij het parent-object (dat het uitvoerbaar bestand voorstelt) een extra objectbestand (dat de DLL voorstelt) bij te linken. De eerste stap is natuurlijk te bepalen welke DLL s aan het uitvoerbaar bestand toe te voegen Bepalen van de benodigde DLL s De importtabellen van het uitvoerbaar bestand worden bekeken en de DLL s waarvan het uitvoerbaar bestand rechtstreeks afhankelijk is worden bepaald. Deze DLL s worden aan een lijst van benodigde DLL s toegevoegd, de DLL s uit deze lijst worden vervolgens één voor één als objectbestand ingelezen en aan het parent-object toegevoegd. Voor elke toegevoegde DLL worden de importtabellen ook bekeken en de DLL s waarvan het afhankelijk is (en waarvan het uitvoerbaar bestand dus eventueel indirect afhankelijk is) bepaald en aan de lijst van benodigde DLL s toegevoegd. Het is mogelijk dat de delen die we nodig hebben uit een bepaalde DLL (de delen die geassocieerd zijn met de uit die DLL geïmporteerde symbolen) geen uit andere DLL s geïmporteerde symbolen gebruiken, en dus eigenlijk niet afhankelijk zijn van enige andere DLL. Dit is echter nog niet geweten op het moment dat we proberen te bepalen van welke DLL s het uitvoerbaar bestand (direct of indirect) afhankelijk is. Daarom worden alle DLL s waarvan het uitvoerbaar bestand eventueel afhankelijk is aan 40

50 het bestand toegevoegd, en de lijst van benodigde DLL s bestaat dus niet per se uit DLL s die echt benodigd zijn, maar eerder uit DLL s die eventueel benodigd zijn. Bij het bepalen van de benodigde DLL s moet natuurlijk ook rekening gehouden worden met export forwarding (zie Sectie 2.5.1) en het API-set-schema (zie Sectie 2.6.2). Indien we een symbool uit een DLL willen importeren dat eigenlijk doorverwezen wordt, dan is de DLL waarnaar het doorverwezen wordt ook benodigd. Indien we een een symbool importeren uit een virtuele DLL, dan is de bijhorende logische DLL benodigd. In het geval dat het uitvoerbaar bestand afhankelijk is van kernel32 zie Figuur 2.11 zullen naast kernel32 ook KernelBase en ntdll aan het bestand worden toegevoegd. Is het bestand afhankelijk van bijvoorbeeld user32 dan zullen alle op de figuur aanwezige DLL s aan het bestand worden toegevoegd. Deze DLL s bevatten veel code en data die in de applicatie eigenlijk niet gebruikt wordt, omdat ze geassocieerd is aan symbolen die het oorspronkelijk uitvoerbaar bestand niet importeerde. Het is zelfs mogelijk dat er DLL s toegevoegd worden waaruit de applicatie niets nodig heeft. In Sectie 4.4 wordt er besproken hoe we zo veel mogelijk van deze overbodige code en data verwijderen Reconstrueren van relocaties Alvorens het objectbestand dat de DLL voorstelt bij het parent-object bij gelinkt wordt, wordt er nog een extra bewerking uitgevoerd. Er bestaan namelijk referenties die van één sectie naar een andere sectie binnen een DLL gaan (voor een voorbeeld van zo n referentie zie Figuur 2.10). Als een DLL (of delen ervan) aan een uitvoerbaar bestand toegevoegd wordt, moeten de referenties tussen de toegevoegde secties behouden blijven om te verzekeren dat de toegevoegde delen correct blijven functioneren. Daarom moeten we een beeld van deze referenties opbouwen. De enige informatie uit het PE-formaat die we hiervoor kunnen gebruiken zijn de base relocaties (zie Sectie 2.5.3). Een base relocatie wijst steeds naar een locatie binnen een sectie van een PE-bestand waarop er een absoluut adres te vinden is. Deze absolute adressen wijzen naar een adres in een tweede sectie van het bestand. Deze twee secties zijn meestal verschillend maar ze kunnen ook dezelfde zijn, in welk geval het een interne referentie is. Voor elke base relocatie bepalen we in Diablo deze twee secties en voegen aan de relocatie-informatie die Diablo bijhoudt een relocatie toe die van het juiste adres in de eerste sectie naar het juiste adres in de tweede sectie wijst. Alle relocaties tussen secties (en ook sommigen binnen secties) worden op deze manier gereconstrueerd. 4.2 Disassembleren Eens alle eventueel benodigde DLL s aan het uitvoerbaar bestand zijn toegevoegd, begint Diablo de.text-secties te disassembleren en de ACVG te construeren. Om de.text-secties van systeembibliotheken op een correcte manier te disassembleren moesten er echter een aantal aanpassingen gebeuren in Diablo. In alle systeembibliotheken (behalve kernel32) is het namelijk zo dat de data die gewoonlijk aanwezig is in de.rdata-sectie, in de.text-sectie is geplaatst. 41

51 Deze data staat niet gewoon op het einde van de.text-sectie, maar is door de hele sectie verspreid. Daarnaast plaatst Visual Studio (de IDE waarmee de meeste Windows-applicaties en ook de systeembibliotheken gemaakt worden) ook alle sprongtabellen (zie verder) in de.text-sectie, in tegenstelling tot andere compilers die deze in de.rdata-sectie plaatsen. Om correct met al deze data in de.text-secties om te gaan, moeten deze recursief gedisassembleerd worden (zie Sectie 2.3.2). Diablo bezat echter enkel functionaliteit om lineair te disassembleren, en daarom heb ik ondersteuning geschreven voor recursief disassembleren. Enkel.text-secties afkomstig uit DLL s worden recursief gedisassembleerd. Zoals besproken in Sectie kan er niet altijd een perfect onderscheid tussen code en data gemaakt worden. Tenzij een bestand geobfusceerd is met als specifiek doel het belemmeren van recursief disassembleren kunnen we er wel van uitgaan dat er geen data verkeerdelijk als code herkend is. Vanwege indirect controleverloop zal er wel veel code als data herkend worden, dit veroorzaakt een probleem dat we in Sectie 4.3 zullen bespreken. Een mogelijke oplossing wordt besproken in Sectie Implementatie van recursief disassembleren Het is mogelijk dat een PE-bestand meerdere.text-secties bevat. In Diablo worden secties afzonderlijk gedisassembleerd. Bij het recursief disassembleren is dit echter niet wenselijk, omdat we bij het volgen van het controleverloop mogelijk bij een instructie in een andere.textsectie terecht zouden komen. Omdat secties afzonderlijk worden gedisassembleerd zouden we het controleverloop niet kunnen volgen naar een andere sectie en zou de code in deze sectie dus mogelijkerwijs niet gedisassembleerd worden. Om dit te vermijden wordt er (voor het disassembleren) voor gezorgd dat er maar één.text-sectie meer aanwezig is in de DLL, dit door alle.text-secties (indien er meerdere zijn) samen te voegen tot één sectie. De adressen waarop we beginnen te disassembleren zijn die van de initialisatieroutine en de geëxporteerde functies. Het is niet mogelijk om aan de hand van enkel het PE-bestand te beslissen welke geëxporteerde symbolen functies zijn en welke variabelen zijn. Daarom wordt er in Diablo een lijst gebruikt met alle door systeembibliotheken geëxporteerde symbolen waarvan we uit ervaring weten dat ze variabelen zijn. Bij het disassembleren wordt er in deze lijst opgezocht of een geëxporteerd symbool een variabele is of niet. Momenteel bevat deze lijst nog maar één symbool. Voor elk adres van een geëxporteerde functie of van de initialisatieroutine roepen we een functie op die lineair begint te disassembleren tot ze een reeds gedisassembleerde instructie tegenkomt, of een controleverloopinstructie disassembleert. Indien de controleverloopinstructie een return-instructie is of een instructie die de uitvoering laat stoppen (zoals een interrupt), dan stopt de disassembleerfunctie met disassembleren. Indien het een controleverloopinstructie is die naar een andere plaats in de applicatie kan gaan, dan volgen we deze door de functie recursief op te roepen met het doeladres als argument. Dit laatste doen we enkel in geval van direct controleverloop aangezien het doel van indirect controleverloop niet gekend is. Het doel zou eventueel nog via constantenpropagatie berekend kunnen worden, maar dit is niet geïmplementeerd. 42

52 Nadat alle instructies in de mate van het mogelijke gedisassembleerd zijn, wordt de rest van de sectie in Diablo gekenmerkt als data. Voor elke locatie waarop er geen instructie herkend is, zal Diablo een data-instructie genereren. Zo n instructie is één byte groot en geeft aan dat er op dat adres data aanwezig is. Als er op een later moment BBL s gemaakt worden, vormt elk contigu bereik van data-instructies één data-bbl Sprongtabellen Indirect controleverloop kan doorgaans niet gevolgd worden bij het recursief disassembleren. Er is echter één vorm van indirect controleverloop dat we wel kunnen volgen, namelijk hetgeen dat te maken heeft met sprongtabellen. Zo n tabel bestaat uit een aantal adressen waarheen gesprongen kan worden vanaf een indirecte jmp-instructie. Dit wordt gebruikt bij het implementeren van switch-statements. Een voor een switch-statement gegenereerde, indirecte jmp-instructie kan er bijvoorbeeld als volgt uitzien: jmp [sprongtabel + 4 case]. Hier is sprongtabel het adres van de sprongtabel, 4 de lengte van een adres in bytes en case de index in de tabel die overeenkomt met de specifieke case. Sprongtabellen worden gevonden door mogelijke instructiepatronen die wijzen op de implementatie van een switch-statement te herkennen. Deze patronen eindigen altijd in een indirecte jmp-instructie. Eens gevonden, wordt de disassembleerfunctie voor elk adres binnen de sprongtabel opgeroepen. Zo slagen we erin ook dit indirect controleverloop te volgen. Doordat het vinden van sprongtabellen steunt op het herkennen van mogelijke patronen worden sommige sprongtabellen niet gevonden (bv. diegenen die geassocieerd zijn met ongekende patronen en andere compilers). De sprongtabellen zelf worden herkend als zijnde data in de.text-sectie en komen dus terecht in data-bbl s. Voor het verwijderen van overbodige code en data in Sectie 4.4 is het voordelig als een data-bbl dat een sprongtabel bevat enkel die sprongtabel bevat. Daarom worden de nodige aanpassingen gemaakt zodat eventuele data gelegen voor de sprongtabel in een afzonderlijk data-bbl terechtkomt, en hetzelfde gebeurt voor eventuele data gelegen na de sprongtabel. 4.3 Statisch linken van dynamisch gelinkte bestanden In de vorige secties werd besproken hoe de benodigde DLL s als objectbestanden aan het parent-object werden toegevoegd en vervolgens de.text-secties van de toegevoegde DLL s en het uitvoerbaar bestand werden gedisassembleerd. Eens dat gebeurd is bouwt Diablo een ACVG op die we gaan aanpassen. Omdat functies die niet bereikbaar zijn vanaf het beginknoop van de applicatie niet door Diablo herkend worden, gebruiken we de force reachablevlag op elke geëxporteerde functie die we nodig hebben (net als in Sectie 3.3.1). Omdat het uitvoerbaar bestand en de DLL s van elkaars functionaliteit gebruik maken via dynamisch linken zijn er geen relocaties tussen secties afkomstig uit verschillende bestanden, en bevat de opgebouwde ACVG geen verbindingen tussen de deelgrafen die deze verschillende bestanden voorstellen. Om verbindingen te creëren tussen deze niet onderling verbonden deelgrafen en alle bestanden feitelijk statisch te linken moet elk dynamisch gebruik van een symbool 43

53 Figuur 4.1: Een voorbeeld van een relocatie op een data-instructie. aangepast worden naar een statisch gebruik van het symbool. Het bepalen van alle instructies die een dynamisch symbool gebruiken gebeurt analoog aan de manier waarop dit bij het encrypteren van de meta-informatie in Sectie plaatsvindt. De relocatie-informatie bijgehouden in Diablo bestaat op dit moment niet enkel uit relocaties binnen het oorspronkelijke uitvoerbare bestand maar ook uit relocaties binnen de toegevoegde DLL s. We lopen over alle relocaties en zoeken die relocaties die naar één van de IAT s (elke toegevoegde DLL kan ook een IAT hebben) wijzen. Deze relocaties zijn afkomstig van de gezochte instructies, maar aangezien bij het recursief disassembleren niet alle instructies herkend werden, is het mogelijk dat sommige van deze instructies data-instructies zijn. Elke gevonden instructie (met als één van de operanden een adres in een IAT) zal aangepast worden om direct gebruik te maken van het adres van het corresponderende symbool, behalve wanneer het een data-instructie is. Op Figuur 4.1 zien we een voorbeeld van zo n data-instructie waarvan een relocatie komt die naar de IAT wijst. Deze instructie is de eerste van vier data-instructies die eigenlijk een adres binnen de IAT bevatten (0x in het voorbeeld). De opcode-bytes van de eigenlijke instructie waarvan dit adres een operand bestaan uit data-instructies gelegen voor de instructie met de relocatie. Gezien deze eigenlijke instructie niet gedisassembleerd is, kennen we zijn type noch de lengte van de opcode. De instructie op dit moment in het proces nog proberen te disassembleren is niet gegarandeerd om het juiste resultaat te geven. We weten namelijk niet of we de opcode van de eigenlijke instructie bestaat uit één, twee of meerdere bytes. We kunnen de eigenlijke instructie dus niet aanpassen, en relocaties komende van data-instructies worden daarom in de huidige implementatie gewoon verwijderd. Mocht deze instructie tijdens de uitvoering van de herschreven applicatie toch uitgevoerd worden zou dit tot een fout leiden. Een mogelijke oplossing voor dit probleem wordt voorgesteld in Sectie Elke echte instructie die gevonden wordt, wordt wel aangepast. Eerst wordt het gebruikte geïmporteerde symbool gevonden aan de hand van de locatie in de IAT waar de relocatie naar wijst. Met behulp van het geïmporteerde symbool zoeken we het overeenkomstige geëxporteerde symbool (waarvan de definitie aanwezig is in een toegevoegde DLL). Hierbij wordt natuurlijk rekening gehouden met export forwarding en het API-set-schema, en zowel 44

54 import via naam als via ordinaal worden ondersteund. Eens het geëxporteerde symbool gevonden is, wordt er een statische verbinding gemaakt tussen het adres van het symbool en de instructie die het gebruikt. Er zijn twee manieren waarop deze verbinding gemaakt kan worden. Indien de instructie een call of een jmp is, wordt de controleverloopgraaf aangepast zodat er een passende pijl van het instructie-bbl naar het BBL geassocieerd aan het geëxporteerd symbool gaat. Dit zorgt er ook voor dat de instructie aangepast wordt om direct in plaats van indirect gebruik te maken van het operand. In de andere gevallen (indien het functie-adres als data gebruikt wordt, of het symbool een variabele is) worden er geen aanpassingen gemaakt in de controleverloopgraaf. De relocatie zelf wordt aangepast om rechtstreeks naar het adres van het geëxporteerd symbool te wijzen (in plaats van naar de IAT), en de instructie wordt aangepast van een indirect naar een direct gebruik van het operand. Op het einde van deze fase zijn de symbolen die van tevoren dynamisch gevonden werden nu al gevonden, en zijn de nodige verbindingen tussen het oorspronkelijk uitvoerbaar bestand en de toegevoegde DLL s (onderling) gemaakt. De indirectie die aanwezig was om het gebruik van dynamische symbolen mogelijk te maken is verdwenen, en er zijn geen relocaties meer aanwezig die naar een IAT wijzen. Dit laatste is enkel zo omdat ook relocaties die van datainstructies kwamen verwijderd zijn. 4.4 Verwijderen van overbodige code en data Het verwijderen van de overbodige uit DLL s afkomstige code en data komt eigenlijk neer op het elimineren van onbereikbare code en data (zie Sectie 2.2.3). Nadat alle nodige verbindingen gemaakt zijn, maken we dan ook gebruik van deze functionaliteit om de knopen die niet verbonden zijn met de beginknoop (en dus niet gebruikt worden) uit de ACVG te verwijderen. Na deze operatie zal er echter nog steeds veel overbodige code en data aanwezig zijn. Een DLL is net als een uitvoerbaar bestand linker-uitvoer. Alle adressen van symbolen binnen het bestand zijn reeds berekend, met als gevolg dat er symboolinformatie (behalve over dynamische symbolen) noch relocatie-informatie (behalve base relocaties) in afzonderlijke structuren aanwezig is. Deze informatie wordt normaal gezien door Diablo gereconstrueerd door het linkerproces te emuleren, en vervolgens gebruikt om een nauwkeurige representatie van de interne afhankelijkheden van een bestand op te bouwen (zie Sectie 2.2.1). Omdat we niet beschikken over de objectbestanden waaruit de toegevoegde DLL s zijn opgebouwd (laat staan de bijhorende linker maps), kunnen we het linkerproces voor deze DLL s niet emuleren. We kunnen enkel de relevante informatie die aanwezig is in het PE-formaat (de base relocaties en de informatie over dynamische symbolen) gebruiken, en bijgevolg is de opgebouwde representatie veel minder nauwkeurig dan normaal gezien. Het is dit gebrek aan nauwkeurigheid in de representatie van de toegevoegde DLL s die ons parten speelt bij het verwijderen van overbodige code en data. Van de data-secties afkomstig uit het uitvoerbaar bestand is geweten uit welke subsecties 45

55 (afkomstig uit de objectbestanden) deze zijn opgebouwd. Er wordt dus voor al deze subsecties afzonderlijk gekeken of deze verbonden zijn met de beginknoop (en dus of ze verwijderd kunnen worden). Voor de data-secties afkomstig uit toegevoegde DLL s is dit niet het geval. Deze bevatten slechts één subsectie (die qua inhoud gelijk is aan zijn parent-sectie) en er is niets geweten over de oorspronkelijke subsecties waaruit ze zijn opgebouwd. Bijgevolg is het zo dat er in realiteit subsecties zijn die niet verbonden zijn met de beginknoop (omdat deze bijvoorbeeld bestaan uit data geassocieerd aan een niet-gebruikte geëxporteerde functie) en dus eigenlijk verwijderd zouden kunnen worden, maar waarvan we niet weten dat ze bestaan. Deze subsecties kunnen ook als enige verbonden zijn met andere subsecties of BBL s (in geval van functie-pointers in een data-sectie) die eigenlijk ook verwijderd zouden kunnen worden, maar ook dit is niet mogelijk wegens het gebrek aan nauwkeurigheid. Daarnaast leidt het recursief disassembleren ook tot onnauwkeurigheid. Alle bytes in een.text-sectie die niet als onderdeel van een instructie zijn herkend, zijn gekenmerkt als data en zitten in data-bbl s. Deze data-bbl s bestaan uit contigue geheugenbereiken die normaliter begrensd worden door echte BBL s. Ze kunnen dus bestaan uit meerdere niet gedisassembleerde functies (of delen ervan) en data-subsecties die samengevoegd zijn. Om deze nauwkeurigheid enigszins te verbeteren zijn alle sprongtabellen (waarvan we weten dat ze eigenlijk afzonderlijke subsecties zijn) in afzonderlijke data-bbl s geplaatst. 4.5 Initialisatieroutines Eens een DLL in het geheugen geladen is wordt er indien aanwezig een initialisatieroutine uitgevoerd [60][61]. Deze routine wordt niet alleen opgeroepen als een DLL aan een proces wordt toegevoegd maar ook als ze eruit verwijderd wordt. Dit verwijderen gebeurt als het proces eindigt, maar kan ook gebeuren tijdens de uitvoering (de DLL wordt dan gelost). Ook voor elke nieuwe thread die start en elke oude thread die eindigt wordt de initialisatieroutine opgeroepen. De context waarin ze opgeroepen wordt kan afgeleid worden van de argumenten, en voor elk van deze situaties kan er verschillende code uitgevoerd worden. Op deze manier wordt er aan initialisatie en finalisatie van een DLL gedaan, en is het mogelijk om Thread Local Storage (TLS) te voorzien [62]. Er moet bij het inlijven van delen van een DLL bij het uitvoerbaar bestand voor gezorgd worden dat de bijhorende initialisatieroutine op de juiste momenten aangeroepen wordt. In de huidige implementatie wordt deze enkel aangeroepen bij het opstarten van de applicatie. Er wordt voor gezorgd dat alle initialisatieroutines gevonden worden als functie door Diablo (m.b.v. de force reachable-vlag), en aan de lijst met uit te voeren initialisatieroutines toegevoegd worden. Er wordt extra code toegevoegd die als nieuw beginpunt van de applicatie zal dienen en deze initialisatieroutines met de juiste argumenten zal aanroepen. De initialisatieroutine voor een DLL zou idealiter enkel aangeroepen worden indien de data die geïnitialiseerd wordt ook daadwerkelijk gebruikt wordt in de delen van de DLL die we willen bijhouden. Het is echter moeilijk om dit te bepalen en daarnaast is het mogelijk dat de routine functies oproept die een neveneffect hebben. Daarom verkiezen we om zodra er ook maar iets uit een DLL gebruikt wordt in het uiteindelijke bestand haar initialisatieroutine bij 46

56 te houden, met als gevolg dat ook alle code en data geassocieerd aan die initialisatieroutine niet verwijderd worden. We hebben echter in Sectie gezien dat we niet van tevoren weten of een DLL echt nodig is of niet, en in de huidige implementatie worden dus alle initialisatieroutines (en verwante code en data) bijgehouden en uitgevoerd. Een mogelijke uitbreiding die dit probleem oplost wordt besproken in Sectie Partieel statisch linken Een volledig statisch gelinkt uitvoerbaar bestand dat gebruik maakt van systeemoproepen zal normaal gezien enkel werken op de versie van Windows waarvoor het gelinkt is. Hoofdstuk 5 presenteert een methode die een volledig statisch applicatie compatibel maakt met meerdere versies van Windows, maar in deze sectie bespreken we een tussenoplossing die geïmplementeerd werd: partieel statisch linken. Dit houdt in dat Diablo een uitvoerbaar bestand genereert waarin alle niet-systeemspecifieke DLL s zijn toegevoegd, waardoor het bestand enkel nog maar afhankelijk is van de Windows API (t.t.z. de Win32-bibliotheken). Het gebruik van deze API wordt dan verborgen via het encrypteren van meta-informatie. Het bepalen van de nog uit Win32-bibliotheken te importeren symbolen gebeurt door (na het statisch linken) alle relocaties te overlopen en diegene te zoeken die nog steeds naar een IAT wijzen. Als we geen Win32-bibliotheken toevoegen aan het uitvoerbaar bestand zijn er een aantal moeilijkheden die we meestal kunnen vermijden: het API-set-schema, export forwarding, de aanwezigheid van read-only data in de.text-sectie, en natuurlijk de aanwezigheid van systeemoproepen in het uitvoerbaar bestand. Om de meta-informatie te encrypteren gebruiken we de methode voorgesteld in Hoofdstuk 3. Deze voegt glue code toe aan het bestand, we gebruiken de initialisatiefunctie uit deze glue code om de mogelijke initialisatieroutines van de toegevoegde DLL s op te roepen. Indien het oorspronkelijk uitvoerbaar bestand enkel gebruik maakt van Win32-bibliotheken is er geen verschil tussen het encrypteren van meta-informatie en partieel statisch linken. Deze tussenoplossing is dan ook enkel van nut indien er een DLL gebruikt wordt in de applicatie die ontwikkeld werd door een derde partij. Delen van een zelf-ontwikkelde DLL zouden namelijk beter op broncode-niveau aan het uitvoerbaar bestand toegevoegd kunnen worden. 4.7 Beperkingen en mogelijke uitbreidingen Iteratief bepalen van benodigde DLL s In de huidige implementatie worden alle DLL s toegevoegd waarvan het te herschrijven uitvoerbaar bestand eventueel afhankelijk is alvorens een ACVG op te bouwen en te bepalen welke delen uit deze DLL s we eigenlijk nodig hebben. Op deze manier worden er mogelijkerwijs DLL s toegevoegd die uiteindelijk helemaal niet gebruikt blijken te worden. Dit is al bij een aantal eenvoudige voorbeeldapplicaties gebleken, en is ook mogelijk bij meer ingewikkelde applicaties. Indien een onnodige DLL een initialisatieroutine heeft, zal deze (samen met geassocieerde code en data) echter wel aanwezig zijn in het uiteindelijk uitvoerbaar bestand. Een mogelijke uitbreiding van de huidige implementatie die het toevoegen van onnodige DLL s 47

57 Figuur 4.2: Een voorbeeld van het gebruik van een afhankelijkheidsgraaf. (op enkele uitzonderingen na) vermijdt, is om ze één voor één toe te voegen en voor elke DLL afzonderlijk te bepalen welke delen eruit eigenlijk benodigd zijn. Dit zal het probleem met de initialisatieroutines oplossen en de prestatie van de implementatie verbeteren. Om de DLL s iteratief toe te kunnen voegen moet er eerst een afhankelijkheidsgraaf opgesteld worden die de afhankelijkheden tussen DLL s voorstelt. Het opstellen van deze graaf wordt dan de nieuwe eerste stap van de methode en wordt uitgevoerd in plaats van het bepalen van de benodigde DLL s. Dit opstellen gebeurt aan de hand van de importtabellen van de DLL s, en houdt rekening met export forwarding en het API-set-schema. Het uitvoerbaar bestand wordt de beginknoop van de graaf, en elke DLL is bereikbaar vanaf deze knoop (voor een voorbeeld van zo n afhankelijkheidsgraaf, zie Figuur 4.2). Eens de graaf opgesteld is, beginnen we met het toevoegen van DLL s. We kiezen een DLL waarvan enkel het uitvoerbaar bestand afhankelijk is, voegen deze toe, bouwen een ACVG op en verwijderen de onnodige delen van de DLL. Alvorens de ACVG terug om te zetten naar gewone secties, passen we de afhankelijkheidsgraaf aan. De net toegevoegde DLL wordt uit de graaf verwijderd en nieuwe afhankelijkheden tussen het uitvoerbaar bestand en DLL s (afkomstig van de nieuw toegevoegde delen) worden aangebracht. Indien een knoop niet meer bereikbaar is vanaf de beginknoop wordt deze uit de graaf verwijderd. Als de hele procedure doorlopen is en we terug over gewone secties beschikken, kiezen we weer een DLL waarvan enkel het uitvoerbaar bestand afhankelijk is, voegen deze toe etc. tot er geen DLL s meer overblijven in de graaf. In het voorbeeld op Figuur 4.2 wordt eerst DLL1 toegevoegd. Hierdoor wordt het uitvoerbaar bestand afhankelijk van DLL2, dat vervolgens toegevoegd wordt. Beide DLL s zijn afhankelijk van DLL3, maar geen van de toegevoegde delen uit de eerste twee DLL s is eigenlijk afhankelijk van DLL3. Bijgevolg wordt deze DLL niet toegevoegd, en belandt zijn initialisatieroutine dus niet in het herschreven uitvoerbaar bestand. Twee of meer DLL s die van elkaar afhankelijk zijn (bv. user32 en gdi32 op Figuur 2.11) vormen een uitzonderingsgeval. Deze vormen een cyclische deelgraaf die wel als één knoop 48

Werking van de Office Connector, en het oplossen van fouten.

Werking van de Office Connector, en het oplossen van fouten. Werking van de Office Connector, en het oplossen van fouten. De Office Connector zorgt ervoor dat de Microsoft Officeomgeving gebruikt kan worden als ontwerp en genereeromgeving voor documenten waarbij

Nadere informatie

Process Mining and audit support within financial services. KPMG IT Advisory 18 June 2014

Process Mining and audit support within financial services. KPMG IT Advisory 18 June 2014 Process Mining and audit support within financial services KPMG IT Advisory 18 June 2014 Agenda INTRODUCTION APPROACH 3 CASE STUDIES LEASONS LEARNED 1 APPROACH Process Mining Approach Five step program

Nadere informatie

Security Les 1 Leerling: Marno Brink Klas: 41B Docent: Meneer Vagevuur

Security Les 1 Leerling: Marno Brink Klas: 41B Docent: Meneer Vagevuur Security Les 1 Leerling: Klas: Docent: Marno Brink 41B Meneer Vagevuur Voorwoord: In dit document gaan we beginnen met de eerste security les we moeten via http://www.politiebronnen.nl moeten we de IP

Nadere informatie

UBC op Microsoft Windows 64-bits

UBC op Microsoft Windows 64-bits UBC op Microsoft Windows 64-bits Inleiding Op de 64-bits varianten van Windows werkt de UBC (en vele andere pakketten) op een andere manier dan op de oudere 32-bits varianten van deze Windows versies.

Nadere informatie

Software Test Plan. Yannick Verschueren

Software Test Plan. Yannick Verschueren Software Test Plan Yannick Verschueren November 2014 Document geschiedenis Versie Datum Auteur/co-auteur Beschrijving 1 November 2014 Yannick Verschueren Eerste versie 1 Inhoudstafel 1 Introductie 3 1.1

Nadere informatie

Introductie in flowcharts

Introductie in flowcharts Introductie in flowcharts Flow Charts Een flow chart kan gebruikt worden om: Processen definieren en analyseren. Een beeld vormen van een proces voor analyse, discussie of communicatie. Het definieren,

Nadere informatie

De Invloed van Innovatiekenmerken op de Intentie van Leerkrachten. een Lespakket te Gebruiken om Cyberpesten te Voorkomen of te.

De Invloed van Innovatiekenmerken op de Intentie van Leerkrachten. een Lespakket te Gebruiken om Cyberpesten te Voorkomen of te. De Invloed van Innovatiekenmerken op de Intentie van Leerkrachten een Lespakket te Gebruiken om Cyberpesten te Voorkomen of te Stoppen The Influence of the Innovation Characteristics on the Intention of

Nadere informatie

Software Reverse Engineering. Jacco Krijnen

Software Reverse Engineering. Jacco Krijnen Software Reverse Engineering Jacco Krijnen Opbouw Inleiding en definitie Techniek Assemblers/Disassemblers Compilers/Decompilers Toepassingen Security Overige Softwarebeveiliging Piracy Anti RE technieken

Nadere informatie

General info on using shopping carts with Ingenico epayments

General info on using shopping carts with Ingenico epayments Inhoudsopgave 1. Disclaimer 2. What is a PSPID? 3. What is an API user? How is it different from other users? 4. What is an operation code? And should I choose "Authorisation" or "Sale"? 5. What is an

Nadere informatie

Werken met SNAP pakketten in Ubuntu 16.04

Werken met SNAP pakketten in Ubuntu 16.04 Werken met SNAP pakketten in Ubuntu 16.04 Eén van de nieuwe zaken die Canonical in zijn Ubuntu-reeks heeft geïntodruceerd zijn SNAP packages. Met convergency in het achterhoofd (zelfde look & feel zowel

Nadere informatie

DALISOFT. 33. Configuring DALI ballasts with the TDS20620V2 DALI Tool. Connect the TDS20620V2. Start DALISOFT

DALISOFT. 33. Configuring DALI ballasts with the TDS20620V2 DALI Tool. Connect the TDS20620V2. Start DALISOFT TELETASK Handbook Multiple DoIP Central units DALISOFT 33. Configuring DALI ballasts with the TDS20620V2 DALI Tool Connect the TDS20620V2 If there is a TDS13620 connected to the DALI-bus, remove it first.

Nadere informatie

Add the standing fingers to get the tens and multiply the closed fingers to get the units.

Add the standing fingers to get the tens and multiply the closed fingers to get the units. Digit work Here's a useful system of finger reckoning from the Middle Ages. To multiply $6 \times 9$, hold up one finger to represent the difference between the five fingers on that hand and the first

Nadere informatie

Risico s van Technologisch Succes in digitale transformatie S T R A T E G I C A D V I S O R

Risico s van Technologisch Succes in digitale transformatie S T R A T E G I C A D V I S O R Risico s van Technologisch Succes in digitale transformatie 2e Risk Event 2019 11 april 2019 The S T R A T E G I C A D V I S O R Ymanagement school of the autonomous University of Antwerp 2 Prof. dr. Hans

Nadere informatie

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE Tentamen Bewijzen en Technieken 1 7 januari 211, duur 3 uur. Voeg aan het antwoord van een opgave altijd het bewijs, de berekening of de argumentatie toe.

Nadere informatie

CTI SUITE TSP DETAILS

CTI SUITE TSP DETAILS CTI SUITE TSP DETAILS TAPI allows an application to access telephony services provided by a telecom PABX. In order to implement its access to ETRADEAL, a TAPI interface has been developed by Etrali. As

Nadere informatie

Het besturingssysteem of operating system, vaak afgekort tot OS is verantwoordelijk voor de communicatie van de software met de hardware.

Het besturingssysteem of operating system, vaak afgekort tot OS is verantwoordelijk voor de communicatie van de software met de hardware. Het besturingssysteem of operating system, vaak afgekort tot OS is verantwoordelijk voor de communicatie van de software met de hardware. Het vormt een schil tussen de applicatiesoftware en de hardware

Nadere informatie

Non Diffuse Point Based Global Illumination

Non Diffuse Point Based Global Illumination Non Diffuse Point Based Global Illumination Karsten Daemen Thesis voorgedragen tot het behalen van de graad van Master of Science in de ingenieurswetenschappen: computerwetenschappen Promotor: Prof. dr.

Nadere informatie

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE. Toets Inleiding Kansrekening 1 22 februari 2013

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE. Toets Inleiding Kansrekening 1 22 februari 2013 FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE Toets Inleiding Kansrekening 1 22 februari 2013 Voeg aan het antwoord van een opgave altijd het bewijs, de berekening of de argumentatie toe. Als je een onderdeel

Nadere informatie

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE. Toets Inleiding Kansrekening 1 8 februari 2010

FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE. Toets Inleiding Kansrekening 1 8 februari 2010 FOR DUTCH STUDENTS! ENGLISH VERSION NEXT PAGE Toets Inleiding Kansrekening 1 8 februari 2010 Voeg aan het antwoord van een opgave altijd het bewijs, de berekening of de argumentatie toe. Als je een onderdeel

Nadere informatie

ICARUS Illumina E653BK on Windows 8 (upgraded) how to install USB drivers

ICARUS Illumina E653BK on Windows 8 (upgraded) how to install USB drivers ICARUS Illumina E653BK on Windows 8 (upgraded) how to install USB drivers English Instructions Windows 8 out-of-the-box supports the ICARUS Illumina (E653) e-reader. However, when users upgrade their Windows

Nadere informatie

Handleiding Installatie ADS

Handleiding Installatie ADS Handleiding Installatie ADS Versie: 1.0 Versiedatum: 19-03-2014 Inleiding Deze handleiding helpt u met de installatie van Advantage Database Server. Zorg ervoor dat u bij de aanvang van de installatie

Nadere informatie

Model Driven Software Development: Geen toekomst maar realiteit. 4 juni 2009, WTC, Amsterdam.

Model Driven Software Development: Geen toekomst maar realiteit. 4 juni 2009, WTC, Amsterdam. Model Driven Software Development: Geen toekomst maar realiteit. 4 juni 2009, WTC, Amsterdam. Welke hoort in dit rijtje niet thuis? Weg- en waterbouw Huizen- en kantoorbouw Stedenbouw Auto- en vliegtuigbouw

Nadere informatie

MobiDM App Handleiding voor Windows Mobile Standard en Pro

MobiDM App Handleiding voor Windows Mobile Standard en Pro MobiDM App Handleiding voor Windows Mobile Standard en Pro Deze handleiding beschrijft de installatie en gebruik van de MobiDM App voor Windows Mobile Version: x.x Pagina 1 Index 1. WELKOM IN MOBIDM...

Nadere informatie

2019 SUNEXCHANGE USER GUIDE LAST UPDATED

2019 SUNEXCHANGE USER GUIDE LAST UPDATED 2019 SUNEXCHANGE USER GUIDE LAST UPDATED 0 - -19 1 WELCOME TO SUNEX DISTRIBUTOR PORTAL This user manual will cover all the screens and functions of our site. MAIN SCREEN: Welcome message. 2 LOGIN SCREEN:

Nadere informatie

Ontpopping. ORGACOM Thuis in het Museum

Ontpopping. ORGACOM Thuis in het Museum Ontpopping Veel deelnemende bezoekers zijn dit jaar nog maar één keer in het Van Abbemuseum geweest. De vragenlijst van deze mensen hangt Orgacom in een honingraatpatroon. Bezoekers die vaker komen worden

Nadere informatie

Les 11: systeemarchitectuur virtuele machines

Les 11: systeemarchitectuur virtuele machines Les 11: systeemarchitectuur virtuele machines Geavanceerde computerarchitectuur Lieven Eeckhout Academiejaar 2008-2009 Universiteit Gent Virtuele machines Motivatie Interfaces Virtualisatie: inleiding

Nadere informatie

Een.NET-besturingssysteemtoolkit. Discovering Cosmos. Sijmen J. Mulder

Een.NET-besturingssysteemtoolkit. Discovering Cosmos. Sijmen J. Mulder Een.NET-besturingssysteemtoolkit Discovering Cosmos Sijmen J. Mulder Agenda Boek 1 Cosmos: a very short introduction Boek 2 Modern Operating Systems Pauze Boek 3 The Design and Implementation of the Cosmos

Nadere informatie

Zelftest Java concepten

Zelftest Java concepten Zelftest Java concepten Document: n0838test.fm 22/03/2012 ABIS Training & Consulting P.O. Box 220 B-3000 Leuven Belgium TRAINING & CONSULTING INLEIDING BIJ DE ZELFTEST JAVA CONCEPTEN Om de voorkennis nodig

Nadere informatie

Effecten van een op MBSR gebaseerde training van. hospicemedewerkers op burnout, compassionele vermoeidheid en

Effecten van een op MBSR gebaseerde training van. hospicemedewerkers op burnout, compassionele vermoeidheid en Effecten van een op MBSR gebaseerde training van hospicemedewerkers op burnout, compassionele vermoeidheid en compassionele tevredenheid. Een pilot Effects of a MBSR based training program of hospice caregivers

Nadere informatie

Interaction Design for the Semantic Web

Interaction Design for the Semantic Web Interaction Design for the Semantic Web Lynda Hardman http://www.cwi.nl/~lynda/courses/usi08/ CWI, Semantic Media Interfaces Presentation of Google results: text 2 1 Presentation of Google results: image

Nadere informatie

Enterprise Portfolio Management

Enterprise Portfolio Management Enterprise Portfolio Management Strategische besluitvorming vanuit integraal overzicht op alle portfolio s 22 Mei 2014 Jan-Willem Boere Vind goud in uw organisatie met Enterprise Portfolio Management 2

Nadere informatie

ALGORITMIEK: answers exercise class 7

ALGORITMIEK: answers exercise class 7 Problem 1. See slides 2 4 of lecture 8. Problem 2. See slides 4 6 of lecture 8. ALGORITMIEK: answers exercise class 7 Problem 5. a. Als we twee negatieve (< 0) getallen bij elkaar optellen is het antwoord

Nadere informatie

Het Effect van Verschil in Sociale Invloed van Ouders en Vrienden op het Alcoholgebruik van Adolescenten.

Het Effect van Verschil in Sociale Invloed van Ouders en Vrienden op het Alcoholgebruik van Adolescenten. Het Effect van Verschil in Sociale Invloed van Ouders en Vrienden op het Alcoholgebruik van Adolescenten. The Effect of Difference in Peer and Parent Social Influences on Adolescent Alcohol Use. Nadine

Nadere informatie

WWW.EMINENT-ONLINE.COM

WWW.EMINENT-ONLINE.COM WWW.EMINENT-OINE.COM HNDLEIDING USERS MNUL EM1016 HNDLEIDING EM1016 USB NR SERIEEL CONVERTER INHOUDSOPGVE: PGIN 1.0 Introductie.... 2 1.1 Functies en kenmerken.... 2 1.2 Inhoud van de verpakking.... 2

Nadere informatie

Intermax backup exclusion files

Intermax backup exclusion files Intermax backup exclusion files Document type: Referentienummer: Versienummer : Documentatie 1.0 Datum publicatie: Datum laatste wijziging: Auteur: 24-2-2011 24-2-2011 Anton van der Linden Onderwerp: Documentclassificatie:

Nadere informatie

ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK EN BEHANDELING (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM

ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK EN BEHANDELING (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM Read Online and Download Ebook ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK EN BEHANDELING (DUTCH EDITION) FROM BOHN STAFLEU VAN LOGHUM DOWNLOAD EBOOK : ANGSTSTOORNISSEN EN HYPOCHONDRIE: DIAGNOSTIEK STAFLEU

Nadere informatie

Perceptive Process. Release Notes. Version: 3.5.x

Perceptive Process. Release Notes. Version: 3.5.x Perceptive Process Release Notes Version: 3.5.x Written by: Product Knowledge, R&D Date: December 2015 2015 Lexmark International Technology, S.A. All rights reserved. Lexmark is a trademark of Lexmark

Nadere informatie

Vakgroep CW KAHO Sint-Lieven

Vakgroep CW KAHO Sint-Lieven Vakgroep CW KAHO Sint-Lieven Objecten Programmeren voor de Sport: Een inleiding tot JAVA objecten Wetenschapsweek 20 November 2012 Tony Wauters en Tim Vermeulen tony.wauters@kahosl.be en tim.vermeulen@kahosl.be

Nadere informatie

Aanpassing btw per 1 oktober 2012 Microsoft Dynamics AX

Aanpassing btw per 1 oktober 2012 Microsoft Dynamics AX Aanpassing btw per 1 oktober 2012 Microsoft Dynamics AX Mprise B.V. Newtonstraat 2 P.O. Box 598 3900 AN VEENENDAAL The Netherlands Copyright 2012 Mprise B.V., Veenendaal, The Netherlands All rights reserved.

Nadere informatie

Verschillen in het Gebruik van Geheugenstrategieën en Leerstijlen. Differences in the Use of Memory Strategies and Learning Styles

Verschillen in het Gebruik van Geheugenstrategieën en Leerstijlen. Differences in the Use of Memory Strategies and Learning Styles Verschillen in het Gebruik van Geheugenstrategieën en Leerstijlen tussen Leeftijdsgroepen Differences in the Use of Memory Strategies and Learning Styles between Age Groups Rik Hazeu Eerste begeleider:

Nadere informatie

Opleiding PECB IT Governance.

Opleiding PECB IT Governance. Opleiding PECB IT Governance www.bpmo-academy.nl Wat is IT Governance? Information Technology (IT) governance, ook wel ICT-besturing genoemd, is een onderdeel van het integrale Corporate governance (ondernemingsbestuur)

Nadere informatie

Geslacht, Emotionele Ontrouw en Seksdrive. Gender, Emotional Infidelity and Sex Drive

Geslacht, Emotionele Ontrouw en Seksdrive. Gender, Emotional Infidelity and Sex Drive 1 Geslacht, Emotionele Ontrouw en Seksdrive Gender, Emotional Infidelity and Sex Drive Femke Boom Open Universiteit Naam student: Femke Boom Studentnummer: 850762029 Cursusnaam: Empirisch afstudeeronderzoek:

Nadere informatie

TECHNISCHE UNIVERSITEIT EINDHOVEN Faculteit Wiskunde en Informatica. Examination 2DL04 Friday 16 november 2007, hours.

TECHNISCHE UNIVERSITEIT EINDHOVEN Faculteit Wiskunde en Informatica. Examination 2DL04 Friday 16 november 2007, hours. TECHNISCHE UNIVERSITEIT EINDHOVEN Faculteit Wiskunde en Informatica Examination 2DL04 Friday 16 november 2007, 14.00-17.00 hours. De uitwerkingen van de opgaven dienen duidelijk geformuleerd en overzichtelijk

Nadere informatie

Kwetsbaarheden in BIOS/UEFI

Kwetsbaarheden in BIOS/UEFI Kwetsbaarheden in BIOS/UEFI ONDERZOEKSRAPPORT DOOR TERRY VAN DER JAGT, 0902878 8 maart 2015 Inhoudsopgave Inleiding... 2 Wat is een aanval op een kwetsbaarheid in het BIOS?... 2 Hoe wordt een BIOS geïnfecteerd?...

Nadere informatie

Sparse columns in SQL server 2008

Sparse columns in SQL server 2008 Sparse columns in SQL server 2008 Object persistentie eenvoudig gemaakt Bert Dingemans, e-mail : info@dla-os.nl www : http:// 1 Content SPARSE COLUMNS IN SQL SERVER 2008... 1 OBJECT PERSISTENTIE EENVOUDIG

Nadere informatie

S e v e n P h o t o s f o r O A S E. K r i j n d e K o n i n g

S e v e n P h o t o s f o r O A S E. K r i j n d e K o n i n g S e v e n P h o t o s f o r O A S E K r i j n d e K o n i n g Even with the most fundamental of truths, we can have big questions. And especially truths that at first sight are concrete, tangible and proven

Nadere informatie

De Invloed van Perceived Severity op Condoomgebruik en HIV-Testgedrag. The Influence of Perceived Severity on Condom Use and HIV-Testing Behavior

De Invloed van Perceived Severity op Condoomgebruik en HIV-Testgedrag. The Influence of Perceived Severity on Condom Use and HIV-Testing Behavior De Invloed van Perceived Severity op Condoomgebruik en HIV-Testgedrag The Influence of Perceived Severity on Condom Use and HIV-Testing Behavior Martin. W. van Duijn Student: 838797266 Eerste begeleider:

Nadere informatie

Geheugenbeheer. ICT Infrastructuren 2 december 2013

Geheugenbeheer. ICT Infrastructuren 2 december 2013 Geheugenbeheer ICT Infrastructuren 2 december 2013 Doelen van geheugenbeheer Reloca>e (flexibel gebruik van geheugen) Bescherming Gedeeld/gemeenschappelijk geheugen Logische indeling van procesonderdelen

Nadere informatie

Emotioneel Belastend Werk, Vitaliteit en de Mogelijkheid tot Leren: The Manager as a Resource.

Emotioneel Belastend Werk, Vitaliteit en de Mogelijkheid tot Leren: The Manager as a Resource. Open Universiteit Klinische psychologie Masterthesis Emotioneel Belastend Werk, Vitaliteit en de Mogelijkheid tot Leren: De Leidinggevende als hulpbron. Emotional Job Demands, Vitality and Opportunities

Nadere informatie

Karen J. Rosier - Brattinga. Eerste begeleider: dr. Arjan Bos Tweede begeleider: dr. Ellin Simon

Karen J. Rosier - Brattinga. Eerste begeleider: dr. Arjan Bos Tweede begeleider: dr. Ellin Simon Zelfwaardering en Angst bij Kinderen: Zijn Globale en Contingente Zelfwaardering Aanvullende Voorspellers van Angst bovenop Extraversie, Neuroticisme en Gedragsinhibitie? Self-Esteem and Fear or Anxiety

Nadere informatie

Beter, Sneller, Mooier. Processoren 12 januari 2015

Beter, Sneller, Mooier. Processoren 12 januari 2015 Beter, Sneller, Mooier Processoren 12 januari 2015 Beter! Sneller! Krachtigere CPU: maak instructies die meer doen Snellere CPU: pipeline, out-of-order execution Sneller RAM: cache meer mogelijkheden...

Nadere informatie

Behandeleffecten. in Forensisch Psychiatrisch Center de Rooyse Wissel. Treatment effects in. Forensic Psychiatric Centre de Rooyse Wissel

Behandeleffecten. in Forensisch Psychiatrisch Center de Rooyse Wissel. Treatment effects in. Forensic Psychiatric Centre de Rooyse Wissel Behandeleffecten in Forensisch Psychiatrisch Center de Rooyse Wissel Treatment effects in Forensic Psychiatric Centre de Rooyse Wissel S. Daamen-Raes Eerste begeleider: Dr. W. Waterink Tweede begeleider:

Nadere informatie

Programma's installeren in Linux (toegespitst op Kanotix; Debian/sid)

Programma's installeren in Linux (toegespitst op Kanotix; Debian/sid) Programma's installeren in Linux (toegespitst op Kanotix; Debian/sid) In het kort 1 Probeer eerst met # apt-get install programmanaam. (je kunt ook zoeken naar een programma. Zie hoofdstuk apt. 2 Als je

Nadere informatie

3HUIRUPDQFH0HDVXUHPHQW RI'\QDPLFDOO\&RPSLOHG -DYD([HFXWLRQV

3HUIRUPDQFH0HDVXUHPHQW RI'\QDPLFDOO\&RPSLOHG -DYD([HFXWLRQV 3HUIRUPDQFH0HDVXUHPHQW RI'\QDPLFDOO\&RPSLOHG -DYD([HFXWLRQV Tia Newhall and Barton P. Miller {newhall *, bart}@cs.wisc.edu Computer Sciences University of Wisconsin 1210 W. Dayton St. Madison, WI 53706

Nadere informatie

Lichamelijke factoren als voorspeller voor psychisch. en lichamelijk herstel bij anorexia nervosa. Physical factors as predictors of psychological and

Lichamelijke factoren als voorspeller voor psychisch. en lichamelijk herstel bij anorexia nervosa. Physical factors as predictors of psychological and Lichamelijke factoren als voorspeller voor psychisch en lichamelijk herstel bij anorexia nervosa Physical factors as predictors of psychological and physical recovery of anorexia nervosa Liesbeth Libbers

Nadere informatie

Falende Interpretatie? De Samenhang van Faalangst met Interpretatiebias

Falende Interpretatie? De Samenhang van Faalangst met Interpretatiebias Falende Interpretatie? De Samenhang van Faalangst met Interpretatiebias Failing interpretation? The Relationship between Test Anxiety and Interpretation Bias Kornelis P.J. Schaaphok Eerste begeleider:

Nadere informatie

FAAC DRIVER. Driver install procedure for FAAC boards. Installatieprocedure voor driver voor FAAC-kaarten.

FAAC DRIVER. Driver install procedure for FAAC boards. Installatieprocedure voor driver voor FAAC-kaarten. FAAC DRIVER Driver install procedure for FAAC boards Installatieprocedure voor driver voor FAAC-kaarten www.record-toegangstechniek.nl 1 When a FAAC board (E124 or E145) is connected to the USB port, it

Nadere informatie

Dynamiek met VO-Script

Dynamiek met VO-Script Dynamiek met VO-Script Door Bert Dingemans DLA Ontwerp & Software bert@dla-architect.nl Inleiding Op de SDGN nieuwsgroep voor Visual Objects ontstond laatst een draad van berichten over de nieuwe libraries

Nadere informatie

Voor de database wordt een Access 2000 bestand gebruikt, met voorlopig 1 tabel:

Voor de database wordt een Access 2000 bestand gebruikt, met voorlopig 1 tabel: Eenvoudig voorbeeld. Er wordt verondersteld dat er met VS 2008 EXPRESS gewerkt wordt. Voor de database wordt een Access 2000 bestand gebruikt, met voorlopig 1 tabel: (Sommige schermafdrukken zijn afkomstig

Nadere informatie

Software Processen. Ian Sommerville 2004 Software Engineering, 7th edition. Chapter 4 Slide 1. Het software proces

Software Processen. Ian Sommerville 2004 Software Engineering, 7th edition. Chapter 4 Slide 1. Het software proces Software Processen Ian Sommerville 2004 Software Engineering, 7th edition. Chapter 4 Slide 1 Het software proces Een gestructureerd set van activiteiten nodig om een software systeem te ontwikkelen Specificatie;

Nadere informatie

gedrag? Wat is de invloed van gender op deze samenhang? gedrag? Wat is de invloed van gender op deze samenhang?

gedrag? Wat is de invloed van gender op deze samenhang? gedrag? Wat is de invloed van gender op deze samenhang? Is er een samenhang tussen seksuele attituden en gedragsintenties voor veilig seksueel Is there a correlation between sexual attitudes and the intention to engage in sexually safe behaviour? Does gender

Nadere informatie

7 aug. 2006 Snelstart document Thecus N2100 Y.E.S.box BlackIP Versie 1.0

7 aug. 2006 Snelstart document Thecus N2100 Y.E.S.box BlackIP Versie 1.0 Setup Wizard MET DHCP-server: 1. NA de installatie van de software welke zich op de CD bevindt krijgt u het volgende te zien: 2. V ervolgens gaat de softw are op zoek naar de Thecus Y.E.S.box welke is

Nadere informatie

University of Groningen

University of Groningen University of Groningen De ontwikkeling van prikkelverwerking bij mensen met een Autisme Spectrum Stoornis en de invloed van hulp en begeleiding gedurende het leven. Fortuin, Marret; Landsman-Dijkstra,

Nadere informatie

COGNITIEVE DISSONANTIE EN ROKERS COGNITIVE DISSONANCE AND SMOKERS

COGNITIEVE DISSONANTIE EN ROKERS COGNITIVE DISSONANCE AND SMOKERS COGNITIEVE DISSONANTIE EN ROKERS Gezondheidsgedrag als compensatie voor de schadelijke gevolgen van roken COGNITIVE DISSONANCE AND SMOKERS Health behaviour as compensation for the harmful effects of smoking

Nadere informatie

Pesten onder Leerlingen met Autisme Spectrum Stoornissen op de Middelbare School: de Participantrollen en het Verband met de Theory of Mind.

Pesten onder Leerlingen met Autisme Spectrum Stoornissen op de Middelbare School: de Participantrollen en het Verband met de Theory of Mind. Pesten onder Leerlingen met Autisme Spectrum Stoornissen op de Middelbare School: de Participantrollen en het Verband met de Theory of Mind. Bullying among Students with Autism Spectrum Disorders in Secondary

Nadere informatie

Application interface. service. Application function / interaction

Application interface. service. Application function / interaction Les 5 Het belangrijkste structurele concept in de applicatielaag is de applicatiecomponent. Dit concept wordt gebruikt om elke structurele entiteit in de applicatielaag te modelleren: softwarecomponenten

Nadere informatie

Impact en disseminatie. Saskia Verhagen Franka vd Wijdeven

Impact en disseminatie. Saskia Verhagen Franka vd Wijdeven Impact en disseminatie Saskia Verhagen Franka vd Wijdeven Wie is wie? Voorstel rondje Wat hoop je te leren? Heb je iets te delen? Wat zegt de Programma Gids? WHAT DO IMPACT AND SUSTAINABILITY MEAN? Impact

Nadere informatie

De Samenhang tussen Dagelijkse Stress, Emotionele Intimiteit en Affect bij Partners met een. Vaste Relatie

De Samenhang tussen Dagelijkse Stress, Emotionele Intimiteit en Affect bij Partners met een. Vaste Relatie De Samenhang tussen Dagelijkse Stress, Emotionele Intimiteit en Affect bij Partners met een Vaste Relatie The Association between Daily Stress, Emotional Intimacy and Affect with Partners in a Commited

Nadere informatie

Installation & Usage Biometric Reader - NL. Biometric Reader - NL. Productie Versie: 7.0. Versienummer Handleiding: 1.0.2

Installation & Usage Biometric Reader - NL. Biometric Reader - NL. Productie Versie: 7.0. Versienummer Handleiding: 1.0.2 Biometric Reader - NL Installation & Usage Biometric Reader - NL Productie Versie: 7.0 Versienummer Handleiding: 1.0.2 2013 Inepro B.V. Alle rechten gereserveerd Biometric Reader - NL De meest veelzijde

Nadere informatie

Quality requirements concerning the packaging of oak lumber of Houthandel Wijers vof (09.09.14)

Quality requirements concerning the packaging of oak lumber of Houthandel Wijers vof (09.09.14) Quality requirements concerning the packaging of oak lumber of (09.09.14) Content: 1. Requirements on sticks 2. Requirements on placing sticks 3. Requirements on construction pallets 4. Stick length and

Nadere informatie

Beveiliging van persoonlijke bestanden door middel van encryptie een tutorial door Nick heazk Vannieuwenhoven

Beveiliging van persoonlijke bestanden door middel van encryptie een tutorial door Nick heazk Vannieuwenhoven Beveiliging van persoonlijke bestanden door middel van encryptie een tutorial door Nick heazk Vannieuwenhoven Ten Geleide Voor het beveiligen van onze persoonlijke bestanden zullen we gebruik maken van

Nadere informatie

Interface tussen Stuurbediening en Sony autoaudio

Interface tussen Stuurbediening en Sony autoaudio The information in this document is in Dutch, English version follows later in this document Interface tussen Stuurbediening en Sony autoaudio LET OP! HOEWEL DE UITERSTE ZORGVULDIGHEID IS BETRACHT BIJ

Nadere informatie

Academisch schrijven Inleiding

Academisch schrijven Inleiding - In this essay/paper/thesis I shall examine/investigate/evaluate/analyze Algemene inleiding van het werkstuk In this essay/paper/thesis I shall examine/investigate/evaluate/analyze To answer this question,

Nadere informatie

L.Net s88sd16-n aansluitingen en programmering.

L.Net s88sd16-n aansluitingen en programmering. De L.Net s88sd16-n wordt via één van de L.Net aansluitingen aangesloten op de LocoNet aansluiting van de centrale, bij een Intellibox of Twin-Center is dat de LocoNet-T aansluiting. L.Net s88sd16-n aansluitingen

Nadere informatie

Settings for the C100BRS4 MAC Address Spoofing with cable Internet.

Settings for the C100BRS4 MAC Address Spoofing with cable Internet. Settings for the C100BRS4 MAC Address Spoofing with cable Internet. General: Please use the latest firmware for the router. The firmware is available on http://www.conceptronic.net! Use Firmware version

Nadere informatie

Screen Design. Deliverable 3 - Visual Design. Pepijn Gieles 0877217 19-12-2014. Docent: Jasper Schelling

Screen Design. Deliverable 3 - Visual Design. Pepijn Gieles 0877217 19-12-2014. Docent: Jasper Schelling Screen Design Deliverable 3 - Visual Design Pepijn Gieles 0877217 19-12-2014 Docent: Jasper Schelling Hulp bij het inloggen Inloggen Particulier Personal Banking Private Banking Zakelijk Zoeken in Particulier

Nadere informatie

EM7680 Firmware Update by OTA

EM7680 Firmware Update by OTA EM7680 Firmware Update by OTA 2 NEDERLANDS/ENGLISH EM7680 Firmware update by OTA Table of contents 1.0 (NL) Introductie... 3 2.0 (NL) Firmware installeren... 3 3.0 (NL) Release notes:... 3 4.0 (NL) Overige

Nadere informatie

Handleiding Sportlink Club

Handleiding Sportlink Club Handleiding Sportlink Club Dit document is automatisch gegenereerd. We raden u aan de handleiding online te raadplegen via www.sportlinkclub.nl/support. 1. Installatiehandleiding.........................................................................................

Nadere informatie

Software Test Plan. Yannick Verschueren

Software Test Plan. Yannick Verschueren Software Test Plan Yannick Verschueren Maart 2015 Document geschiedenis Versie Datum Auteur/co-auteur Beschrijving 1 November 2014 Yannick Verschueren Eerste versie 2 December 2014 Yannick Verschueren

Nadere informatie

(1) De hoofdfunctie van ons gezelschap is het aanbieden van onderwijs. (2) Ons gezelschap is er om kunsteducatie te verbeteren

(1) De hoofdfunctie van ons gezelschap is het aanbieden van onderwijs. (2) Ons gezelschap is er om kunsteducatie te verbeteren (1) De hoofdfunctie van ons gezelschap is het aanbieden van onderwijs (2) Ons gezelschap is er om kunsteducatie te verbeteren (3) Ons gezelschap helpt gemeenschappen te vormen en te binden (4) De producties

Nadere informatie

De Relatie tussen Lichamelijke Gezondheid, Veerkracht en Subjectief. Welbevinden bij Inwoners van Serviceflats

De Relatie tussen Lichamelijke Gezondheid, Veerkracht en Subjectief. Welbevinden bij Inwoners van Serviceflats De Relatie tussen Lichamelijke Gezondheid, Veerkracht en Subjectief Welbevinden bij Inwoners van Serviceflats The Relationship between Physical Health, Resilience and Subjective Wellbeing of Inhabitants

Nadere informatie

Bescherming van (software) IP bij uitbesteding van productie

Bescherming van (software) IP bij uitbesteding van productie 12.15 12.40 Bescherming van (software) IP bij uitbesteding van productie Gerard Fianen INDES-IDS BV The choice of professionals Wie zijn wij? Tools, software components and services for the development,

Nadere informatie

Summary 124

Summary 124 Summary Summary 124 Summary Summary Corporate social responsibility and current legislation encourage the employment of people with disabilities in inclusive organizations. However, people with disabilities

Nadere informatie

My Benefits My Choice applicatie. Registratie & inlogprocedure

My Benefits My Choice applicatie. Registratie & inlogprocedure My Benefits My Choice applicatie Registratie & inlogprocedure Welkom bij de My Benefits My Choice applicatie Gezien de applicatie gebruik maakt van uw persoonlijke gegevens en salarisinformatie wordt de

Nadere informatie

Vakinhoudelijke uitwerking Keuzevak Applicatieontwikkeling van het profiel MVI vmbo beroepsgericht

Vakinhoudelijke uitwerking Keuzevak Applicatieontwikkeling van het profiel MVI vmbo beroepsgericht Vakinhoudelijke uitwerking Keuzevak Applicatieontwikkeling van het profiel MVI vmbo beroepsgericht Deze vakinhoudelijke uitwerking is ontwikkeld door het Redactieteam van de Schooleamenbank vmbo voor dit

Nadere informatie

L.Net s88sd16-n aansluitingen en programmering.

L.Net s88sd16-n aansluitingen en programmering. De L.Net s88sd16-n wordt via één van de L.Net aansluitingen aangesloten op de LocoNet aansluiting van de centrale, bij een Intellibox of Twin-Center is dat de LocoNet-T aansluiting. L.Net s88sd16-n aansluitingen

Nadere informatie

Find Neighbor Polygons in a Layer

Find Neighbor Polygons in a Layer Find Neighbor Polygons in a Layer QGIS Tutorials and Tips Author Ujaval Gandhi http://google.com/+ujavalgandhi Translations by Dick Groskamp This work is licensed under a Creative Commons Attribution 4.0

Nadere informatie

Bijlage 2: Informatie met betrekking tot goede praktijkvoorbeelden in Londen, het Verenigd Koninkrijk en Queensland

Bijlage 2: Informatie met betrekking tot goede praktijkvoorbeelden in Londen, het Verenigd Koninkrijk en Queensland Bijlage 2: Informatie met betrekking tot goede praktijkvoorbeelden in Londen, het Verenigd Koninkrijk en Queensland 1. Londen In Londen kunnen gebruikers van een scootmobiel contact opnemen met een dienst

Nadere informatie

Auteur boek: Vera Lukassen Titel boek: Word Gevorderd 2010. 2011, Serasta Uitgegeven in eigen beheer info@serasta.nl Eerste druk: augustus 2012

Auteur boek: Vera Lukassen Titel boek: Word Gevorderd 2010. 2011, Serasta Uitgegeven in eigen beheer info@serasta.nl Eerste druk: augustus 2012 Auteur boek: Vera Lukassen Titel boek: Word Gevorderd 2010 2011, Serasta Uitgegeven in eigen beheer info@serasta.nl Eerste druk: augustus 2012 ISBN: 978-90-817910-7-6 Dit boek is gedrukt op een papiersoort

Nadere informatie

INVLOED VAN CHRONISCHE PIJN OP ERVAREN SOCIALE STEUN. De Invloed van Chronische Pijn en de Modererende Invloed van Geslacht op de Ervaren

INVLOED VAN CHRONISCHE PIJN OP ERVAREN SOCIALE STEUN. De Invloed van Chronische Pijn en de Modererende Invloed van Geslacht op de Ervaren De Invloed van Chronische Pijn en de Modererende Invloed van Geslacht op de Ervaren Sociale Steun The Effect of Chronic Pain and the Moderating Effect of Gender on Perceived Social Support Studentnummer:

Nadere informatie

ALL-CRM Gebruikershandleiding AC-DataCumulator

ALL-CRM Gebruikershandleiding AC-DataCumulator ALL-CRM Gebruikershandleiding AC-DataCumulator Author: Bas Dijk Date: 23-04-2013 Version: v1.2 Reference: 2013, All-CRM 1 Inhoudsopgave 1 Inhoudsopgave 2 2 Inleiding 3 3 Gebruikershandleiding Windows Forms

Nadere informatie

HET BESTURINGSSYSTEEM

HET BESTURINGSSYSTEEM HET BESTURINGSSYSTEEM Een besturingssysteem (ook wel: bedrijfssysteem, in het Engels operating system of afgekort OS) is een programma (meestal een geheel van samenwerkende programma's) dat na het opstarten

Nadere informatie

Archief Voor Kerkelijke Geschiedenis, Inzonderheid Van Nederland, Volume 8... (Romanian Edition)

Archief Voor Kerkelijke Geschiedenis, Inzonderheid Van Nederland, Volume 8... (Romanian Edition) Archief Voor Kerkelijke Geschiedenis, Inzonderheid Van Nederland, Volume 8... (Romanian Edition) Click here if your download doesn"t start automatically Archief Voor Kerkelijke Geschiedenis, Inzonderheid

Nadere informatie

Joe Speedboot Tommy Wieringa

Joe Speedboot Tommy Wieringa Joe Speedboot Tommy Wieringa Thank you very much for downloading. As you may know, people have search numerous times for their chosen books like this, but end up in harmful downloads. Rather than enjoying

Nadere informatie

Inventus Software. Antum Secured Mail / Message System. Gebruikershandleiding

Inventus Software. Antum Secured Mail / Message System. Gebruikershandleiding Inventus Software Antum Secured Mail / Message System Gebruikershandleiding 1 Hoe begin ik? 3 2 Wat is er zoal aanwezig in het hoofdprogramma? 3 3 Hoe decoder ik e-mails of tekstberichten? 4 3.1 Decoderen

Nadere informatie

Gebruikershandleiding Versie 1.07

Gebruikershandleiding Versie 1.07 Gebruikershandleiding Versie 1.07 NE Copyright 2006, by DIALOC ID All rights reserved Gebruikershandleiding Chip programmer DIALOC ID reserves the right to modify the software described in this manual

Nadere informatie

VOP - Unigornel. Maxim Bonnaerens David Vercauteren Henri Verroken. Begeleiders: prof. Bjorn De Sutter, dr. Bart Coppens, dr.

VOP - Unigornel. Maxim Bonnaerens David Vercauteren Henri Verroken. Begeleiders: prof. Bjorn De Sutter, dr. Bart Coppens, dr. FACULTY OF ENGINEERING VOP - Unigornel Maxim Bonnaerens David Vercauteren Henri Verroken Begeleiders: prof. Bjorn De Sutter, dr. Bart Coppens, dr. Jonas Maebe 10 maart 2016 Doelstelling Unigornel: Een

Nadere informatie

De Relatie tussen Werkdruk, Pesten op het Werk, Gezondheidsklachten en Verzuim

De Relatie tussen Werkdruk, Pesten op het Werk, Gezondheidsklachten en Verzuim De Relatie tussen Werkdruk, Pesten op het Werk, Gezondheidsklachten en Verzuim The Relationship between Work Pressure, Mobbing at Work, Health Complaints and Absenteeism Agnes van der Schuur Eerste begeleider:

Nadere informatie

AN URBAN PLAYGROUND AFSTUDEERPROJECT

AN URBAN PLAYGROUND AFSTUDEERPROJECT AN URBAN PLAYGROUND 2005 Het vraagstuk van de openbare ruimte in naoorlogse stadsuitbreidingen, in dit geval Van Eesteren s Amsterdam West, is speels benaderd door het opknippen van een traditioneel stadsplein

Nadere informatie

Running Head: INVLOED VAN ASE-DETERMINANTEN OP INTENTIE CONTACT 1

Running Head: INVLOED VAN ASE-DETERMINANTEN OP INTENTIE CONTACT 1 Running Head: INVLOED VAN ASE-DETERMINANTEN OP INTENTIE CONTACT 1 Relatie tussen Attitude, Sociale Invloed en Self-efficacy en Intentie tot Contact tussen Ouders en Leerkrachten bij Signalen van Pesten

Nadere informatie