Fy fawr, rydw i'n dweud, rydw i ddim yn bwysig, James a Georgie. Rydw i, wrth gwrs, i'n James a mae'n Georgie. Felly, ychydig ychydig. Rydw i'n dweud ar y ffasrwch ar gyfer yw'r cynnwys, yw'r architektur, rwy'n gwybod ar y cyffredinol, fel yw'r cynnwys ar gyfer yw'r cynnwys. Rydw i'n dweud ar gyfer y cyffredinol, ac mae'r sylfaenau cyfrifiadau, yn ymddangos ar gyfer y dyfodol, ac mae'n gofyn ar gael y gyrdd mwy o'r mwy o'r hyn. Yn oedd yn bwysig, ydych chi'n gweithio ym Morgfaenau, gyda'r Gweithes Cynllun gyda'r gweithiau. Yn ddigon o'r Gweithes Cynllun gyda'r gweithiau, gallwn i'n mynd i'r gweithio, felly eich gweithio ym Gweithes Cynllun gyda'r Gweithes Cynllun gyda'r gweithes Cyllun. Gweithes Cynllun gyda'r Gweithes Cynllun, Pretty important nowadays for things like privesque. Also, at NWR, we have a bit of a friendly and internal competition going on, so Nils presented on his version of his Windows Kernel Cards Red T2, obviously, we're trying to beat the number of bugs that he got in his version. Obviously, we're primarily here to try and improve general-prone system security. Initially and most of our research has been focused on Windows, Windows 7, ond we've actually ported the ffuzzer to run on OSX and QNX, and we're looking to start running it properly over the next few months and trying to find some bugs in those OSs as well. So, how hard can it be? If you look over at Twitter, it would appear everyone has Win32K Oday. And so do we. So about a month ago, we did a run. Purely a test run to make sure the ffuzzer was pretty stable. So, as you can see, 16bm, just 48 hours. We got 65 crashes, 13 of those you need. Which, yeah, I didn't think it was too bad, 13 Oday's in Win7. Okay, cool. As it turns out though, we weren't being particularly effective with our ffuzzing. So, for those that don't know, there's a number of syscles in Win7 that are simply just sleeps for all the intensive purposes. So, we got the one there, NT delay execution. So, we managed to find that one, blacklisted, and actually, surprise, surprise, the ffuzzer was a lot more effective. So, we ran it again last week. We haven't triaged all the crashes, which is why we've not spoken in the slides, but we ended up with around 150 crashes and 40 of those were unique. In the end, actually, we crashed our database. We were pushing all these crashes too because it ran out of space for it. So, that seems pretty cool. We are going to release the framework for the ffuzzer. So, the core will be released, but we're not going to release any OS-specific stuff. But throughout the talk, we're going to go through how you would write the OS-specific stuff and give you some examples so you can go away and ffuz the OSes yourself. It's worth bearing in mind when you look at the code that were hackers, not developers. It's pretty dirty in places. So, yeah, bear that in mind. Our sort of test is does it compile great? It probably works it. So, the architecture. Everything is nicely decoupled. So, you've got in there the center of the framework core, which is basically what runs everything on the outside there, which is the OS-specific stuff. Originally, we deved this up in Python, but we've completely rewritten it in C. It's much more efficient, significantly faster, and seems to be finding a lot more bugs for us. So, the first part is the OS API knowledge base. All this is is the OS-specific API that is used by applications to interface with services provided by the OS. So, this is the things devs do to, you know, do things with graphics or interactive devices or do networking, et cetera, et cetera. Many of these will wrap system calls. We'll provide two examples of how we've deved these for Windows and OS X later on in the talk, but we won't be releasing all of our ones. The next part, the next major part of the OS-specific stuff is the system calls. So, system calls are a low-level method for user space to kernel space communications. These have to be implemented per architecture and operating system. So, that's fine for open source systems, you know, OS X or any NIC space system. These tend to be open source. For Windows, it's a little bit more difficult. You have to reverse engineer these ones out or rely on other sources, maybe React OS or something like that. At the bottom there, you can see what a syscall looks like internally to the fuzzer. So, we just have a syscall ID, the arguments for that syscall and then just a return data type if the syscall provides a return. Also, we have a number of fuzzed values. So, there you can just see the fuzzed values you can grab internally from the fuzzer. We use the words fuzzed, but what we don't necessarily mean fuzzed, actually. So, really, we actually want the library calls and syscalls to work, and to get these to work, we actually have to return proper values. So, whilst we occasionally return a properly fuzzed value, most of the time you'll return a normal value, they're going to ensure that the library call and system call works. Yeah. So, the next part is the object store. The object store is used to maintain state across a fuzzing run and it stores OS-specific objects of interest. So, currently, this is handles in windows and file descriptors in NIC systems. It's implemented as just a global array of structures. It's deterministically populated by the fuzzer, and this is quite important for when you want to reproduce crashes. If this wasn't deterministic, then obviously we'd just never be able to reproduce any crashes we found. It's quite easy to retrieve, update, and then certainly objects into the object store. Okay. The next bit is the helper functions. So, helper functions, we use these for things like library calls that require a struct. It works in pretty much the same way as grabbing a fuzzed value. So, if you want to call for a struct for a library call, you make a call to the helper function and it will return you a struct that should work fine in the library call. So, logging. This is actually quite difficult in kernel fuzzing when you keep hitting crashes. So, initially, we didn't have high hopes for the fuzzer. So, all we did was log a PRNG seed. As you might guess, as a fuzzer, we make heavy use of the round function. So, if we can just seed this again, we'll always get a same run again, which makes reproducing quite easy. A bit of an issue, though, is it doesn't generate a standalone test case, which is ultimately where we want to get to. So, what we've moved on to doing is logging C statements. So, our log files are actually complete source files. And all we do is copy and paste these into a template. There are some issues with this. So, occasionally, if we get a B-sod, we'll find that actually the OS hasn't flushed the right to the file before it's B-sodded in the Windows instance. So, we miss out on, let's say, the last call. As a workaround, what we're doing is we're usually able to grab the stack trace and the arguments and everything else and figure out what it was doing. What we're looking towards doing in the future as well is maybe using something like logging over a socket or something like that, which we're hoping will work a little bit better. As you might guess, this is incredibly tedious. So, this is an example of our logging from a library call. What we do is we grab a variable ID to tag on to the end of a variable, and then we assign that variable and call a function. As you can see at the bottom, we log the function call before calling the function in the father to try and ensure that we log the crash before it actually crashes. So, crash detection. There's actually two methods we tried with this. So, the first way we tried was just attaching a kernel debugger while we were executing the fuzzr. Obviously, it requires one or more debugger processes, which slows execution. So, you can either have on the host debugging the VMs or a VM debugging another VM. But the plus point is we instantly analyse any crashes we find. The other option is unattended execution, which is what we're working on at the moment. And this is just letting the OS handle the crash on its own. Much faster execution, and we can run more VMs as well, and we have less wasted CPU cycles. We recover and analyse the crashes upon reboot. Another way we've been looking at, actually, is using hypervisor logs. So, for example, VM where we'll actually log when a host has crashed. And there's some information in there that's actually quite useful. So, this is the way the crash detection story works. When we reboot the box, the first thing we'll do is try and search for a memory dump file. So, this is quite specific to Windows. If we find a memory dump file, we'll match that up with a log file. So, there should only be one log file on the disk, which is the one that caused the crash. If we get that memory dump file, what we do at the moment is under WinBag, bang, analyse, and just grab those details out. And then the three of them, we timestamp and just archive them all off. So, with a number of VMs, so our ultimate goal is to run this across hundreds of VMs, is we need some form of the fuzzard to push this into a central database. So, those three files I just described are actually pushed into a CouchDB database that we just have sat in AWS. This is really useful for us because it means we can actually do de-duplication across all the VMs. So, all we do is hash the stack. If we've seen that hash before, we push the files and increment a counter. If we haven't, then we push the files out into a CouchDB. It also means we can do some other categorisation stuff. So, doing stuff like type of AV, 14IP, bug check ID, et cetera. Closer to the mic. Okay, so that's the overall architecture for the fuzzard. Sound pleasure? Right, yes. So, that was the overall architecture. So, this is what a fuzzing run looks like. The first thing we do is we have a little bootstrap script that we run to prepare a VM for fuzzing. It's just a really simple Python script that installs everything that's required and just fine-tunes the system. So, we'll go through what the windows one of that looks like later on in the talk. We then launch a second Python script, which is a wrapper around the core fuzzard, but what that one does is go away and collects the memory dumps and submits it to the database if it finds them, et cetera, et cetera, as I just said. We then launch the fuzzard binary, and the first thing we do is populate that object store. So, we generate a bunch of valid handles or file descriptors that we can then use for library and system calls straight away. Okay, so then for a predefined number of iterations, we pick up either a library or system call. So, we'll go away, figure out what the arguments are, and then grab the fuzz value, fuzzstrap, or an object from the object store. And then we invoke that call. We check to make sure it's succeeded, and if it gives us a value back that's useful later on, we'll pop that back into the object store. So, you know, library calls or system calls may return a hand or a file descriptor or something similar. We want to keep holding that value and use it later on. At the end, if we didn't get a crash, all we do is just clean up all our temporary files, remove the logs, and just try and revert back to a clean state. Now, currently, all we do is reboot the box. So, this should mostly give us a clean state to work from from the next fuzzing run. Obviously, we can't just start the fuzzer again because if we have done something in a previous fuzzer run that we haven't logged, it's impossible to reproduce that test crash, and it's useless to us. We're actually also looking at how we can possibly revert back to a VM snapshot, as this will guarantee a clean state to start from. A few caveats to be aware of if you're going to take this framework and use it yourselves. We found a number of bugs in the hypervisors, which has meant we haven't placed this up in the crowd. I'm pretty sure people like Amazon are going to get really annoyed with us if we start crashing their hypervisors. So, what we're looking at doing is running it under QEMU, which is a bit inception-y, but should hopefully work. You also need to look into things like... We're also looking into things on how to protect the fuzzer from itself. So, on a number of occasions, somehow the fuzzer has managed to get a handle to itself and kill itself, which is kind of irritating. So, what we're trying to move on to is a method of how we monitor the host that's fuzzing, monitor the guest story from the host. So, if the fuzzer has killed itself or we've hit another sleep or done something else stupid, we can detect that and then start the fuzzer off again. Cool. So, I'm actually going to hand over to Georgie, who's going to go through Windows case study. So, as James already mentioned, we initially started with the idea of developing a Windows kind of fuzzer. And these actually remain our focus, despite of repurposing the fuzzer for OS agnostic operations. So, the second half of the talk is dedicated on getting the fuzzer working efficiently on Windows and basically writing all of these custom modules for Windows operating systems. So, all of these operating system tweaks and object store implementation details that you need to consider when you take the framework and you want to basically use it for fuzzing Windows. I'll be going through several examples for each one of these bullet points. So, basically examples on how we implemented our object store, some examples on what our collection of system calls looks like in Windows, and basically some examples on the wrappers for the library course that we have developed. I'll be ending this with basically what's the process of bootstrapping the Windows VM before we actually start fuzzing. So, the attack surface we decided to focus on is the Win32K subsystem, a pretty well-known attack surface in Windows operating system. This subsystem implements mainly three components, the window manager responsible for desktops, Windows menus, toolbars, the general user interface element, and the graphics device interface also known as GDI, which is in charge of visualisation on the screen, changing colours and basically just general graphics. Win32K.cs also implements some wrappers for direct X calls, and this is not something we have looked at until now. And this is probably not something we'll consider in the future. There is counter components in user land in terms of user mode libraries, a bunch of DLLs provided for application developers to actually interface with the subsystem. So, if you're an application developer, you wouldn't issue a syscall to the Win32K.cs kernel mode driver. You would be going on SDN and looking at how you interface with this kernel mode driver using some library calls that will eventually wrap into a system call. In the Windows operating system, an object is basically a data structure representing some sort of system resource, and this can be anything from a file, process, window, menu, et cetera. There is roughly three types, main types of objects in the Windows operating system, user objects, GDI objects and kernel objects. User objects are implemented to support the window manager. Obviously, GDI objects are implemented to basically manage the graphic device interface, and kernel objects are basically there to implement basic operations in the kernel space, such as process management, memory management, IPC communication, et cetera. One important thing to realise when we talk about objects is that when an application wants to manipulate an object, when an application wants to access an object, it needs to acquire a handle to that object. So if you want to do something with any of the system resources, you need a handle to each one of them in order to basically interface with them. And this is how handles are defined, object handles are defined in the Windows SDK on a really, really low level. They're just basically void pointers managed by the operating system. Now, the implementation details are hidden from the application developer, and the application developer shouldn't really care about how these handles are implemented. And this is just here for a reference. Furthermore, numerous aliases, aliases are defined for more or less any system resource available on the operating system. So this is a snippet from winddeath.h. Head of file from the Windows SDK where a bunch of these declarations actually happen. There's declaration for a handle to a window, declaration for a handle to a bitmap, et cetera. So each one of these system resources will have a sort of specific handle associated, a handle type associated with it. So knowing and realising how fundamental object handles are in the Windows world, it comes as no surprise that we actually decided to preserve object handles in our object store. The object store implementation itself is really straightforward at the moment. It's just a globally accessible array of 120 elements where we just preserve a bunch of handles to numerous system resources. Handles are retrieved from this object store when we need a handle to be passed as an argument to a system or a library call. And should a system or a library call return successfully another handle, we consider this handle and we push it back to the object store. Sorry. If we start running out of, let's say, space in our object store, in this case it's a fixed value of 128, let's say we start running out of slots in this array, we basically start overriding some of the handles from the object store, we basically throw out the oldest handles and we repopulate the object store with some new ones. One more thing to basically notice is the BH Handle struct. The BH Handle struct is our internal representation of a handle. It has two fields, which is the handle itself, as well as the index of the handle in the object store. So handles will be changing values per run. So basically if we grab a handle to a particular window in one run, this handle will have one value. If we grab a handle to an identical window in a second run, this handle will have a different value. So how we grab the same handle twice why basically referring to the handle, not by its value but by its index in the object store. We have implemented a number of functions to interface with the object store I'm talking about. The first one is basically there to bootstrap the object store, populate the object store with some handles before we even start fuzzing so we can actually use some handles as arguments for library and system calls. The second one is the function getRandomHandle. This function will basically look up the store and randomly pick up a handle from it. It will then wrap the handle in a BH handle struct which helps us successfully log the location of the handle in the object store when we issue logging statements. We have another function for querying the object store. This one is getSpecificHandle. This one takes one argument which is basically the index of the handle we want to extract three from the object store. We also have a function for inserting handles back to the object store. Again, should a library call return successfully a handle which push it back to the object store. For populating the knowledge base of system calls, well basically for the majority of them we had to reverse engineer them. We started with mainly system calls implemented in the Win32 case of system. But there is one thing. When I say reverse engineering I don't really mean reversing the logic of the system call itself or how the system call is implemented under the hood. The only details we're interested in are basically the system call ID and the number of arguments for the system call and the data type for each one of these arguments. Optionally, again, the return type for the system call. For the majority of the system calls you have to do some reverse engineering. For some of them you may also refer to ReactOS but this is not necessarily identical to the Windows revision you're working on. To implement the Cisco invocation itself we had to write some assembly snippets and these are specific to both the operating system and the architecture. A little bit more about the assembly snippets in just a second. This is what an extract from our collection of system call looks like. James already mentioned what our internal representation of a system call looks like, the Cisco struct. The Cisco struct has got three fields. The first one is the system call ID. The second one is an array of data types for each one of the arguments consumed by the system call and the third and optional field is basically whether the system call returns any data type we may be potentially interested in. The system call invocation again is implemented per architecture and per operating system. We have what we call system call invocation template. The prototype for the template is the same across the architectures and this is the code with the name buccan underscore Cisco. This template function takes 33 arguments at the moment. The first one being the Cisco ID and the second, basically the rest of these 32 arguments are arguments for the system call itself. Now obviously not every system call would be taking 32 arguments or I don't even know if there is any system call taking 32 arguments at all. The reason we did a fixed number of arguments is because we didn't want to implement a function with a variable number of arguments sort of print that like style. So what we do at the moment is the system call ID as the first argument for this function. We populate the first arguments with the actual data that should be passed to the system call and we just pat the rest of the 32 arguments with some dummy data. Then buccan Cisco is in charge of setting the registers for the invocation of the system call. Pushing each one of these 32 arguments on the stack and then making transition in Kerneland. Once we are in Kerneland the system call is in charge of basically dispatching the request. Taking care of each one and processing each one of the arguments that are actually expected by the system call. The system call will then simply ignore the rest of the 32 arguments on the stack. The system call will eventually return back to the buccan Cisco wrapper. Buccan Cisco wrapper will clean up the stack and return to the main ffuzzing loop. This is just a general reminder on how system call invocation works on Windows. There are six platforms we have arguments pushed on the stack in a reverse order. We have EAX set to the system call ID and then a call is made to the KI fast system call function. Now there is a caveat. This is the case until Windows 7 which is the operating system we have been mostly focused on. I think in Windows 8 and Windows 10 the KI fast system call has been basically inlined in the code. 64, the first four arguments are set in registers. These are RCX, RDX, R8 and R9. If there's any additional arguments that are pushed on the stack then RAX is set to the system call ID and the CPU instructions is made to basically force transition into kernel space. So much for system calls. Now several examples on how to implement OSAPI Knowledge Base. The OSAPI Knowledge Base, the information that we need for it is publicly available on MSDN. These are basically the library calls that application developers are expected to be using when making requests for the operating system. The OSAPI calls Knowledge Base is implemented as one huge array of function pointers to each one of the library call wrappers that we have implemented. I think until a few days ago we had about 500 library call wrappers. So basically 500 functions from GDI32.dll, user32.dll and some other user mod components. As you can imagine this is a really tedious process of implementing wrappers for each one of these. We looked at automating this by basically crawling MSDN, collecting function prototypes and turning these prototypes into library call wrappers in a more or less automated way. But unfortunately we felt miserably with that and we were looking forward to improving our approach. But at the moment, again, each one of these are implemented strictly manually. I'm going to give a few examples now. This is the destroyed current function from MSDN. This function takes no arguments and returns a boolean value. And the wrapper for this call is really simple, really straightforward. Basically we look the call that we are about to make and we make the actual call. That's literally it. So in the log file we basically end up with the exactly same C statement that we are making in our ffuzzer. Something a bit more interesting is the following one destroyed cursor. On the top you have the prototype from MSDN. This one takes a single argument. This argument is basically a handle to a cursor object. And this function returns a boolean again. So what we do in our wrapper we declare the handle but not as a handle we declare it as a BH handle struct that wraps the handle itself as well as the index. We generate a globally unique variable ID that will be appended to the variable name when we make a logging statement. We then log the declaration for the handle while appending the variable ID to the end of the name of the function. We proceed by grabbing a random handle from the object store and assigning it to the handle that we are going to pass to the library call function. Then we log the handle but we log the handle by its index rather than by its actual value. James mentioned this but the object store at any point of the first run is populated in a deterministic way at least in theory. So if we are up to a point where we know the object store has certain handles we can refer to each one of these handles by its index and it should be the case of getting the same handles that we got the last time with the same seed. The last thing we do is basically log the final call that we are about to make. This is the actual call the actual library call and we log this with the respective variables while again appending the variable ID at the end of them. The last thing is just simply make the call. Something a bit more interesting so for example this example demonstrates how to use the helper functions. The helper functions are functions that will generate a valid struct, a window specific struct that is consumed by a library or a system call and I'll be talking about the helper functions in just a bit. But basically this is a function taking two arguments, a handle to a device context and a color type window type. So we start with the same thing again, we declare the variables that we are going to use within the wrapper we generate the variable ID again this will be globally unique across the run we log the handle again notice that we log the handle as a handle not as a BH handle we basically hide the implementation details for a BH handle when it comes to the reproducer test case we drop a random handle and assign it to our variable. The next thing is log the handlebyte index and the next thing is the interesting bit where we actually make a call to a helper function this one is getColorF and each one of the helper functions takes a single argument which is the variable ID so getColorF will basically hide the details for us but it will populate with mostly valid data again this struct that can later on be used by our library call and again the last thing is log the statement, log the call that we are about to make and make the actual call and now a bit more about the helper functions there is just a endless number of custom structs in the windows operating system and they are expected by a number of library calls and system calls and this is where the helper functions come basically for each one of these well obviously we cannot implement for each one of them but for the most common ones consumed by the winter d2k system and library calls we have implemented helper functions so basically we have helper functions for returning rectangles, points, sizes windows etc and again these are mostly valid and they shouldn't really be way too malformed at the bottom of the slide you can basically a snippet from the list of helper functions we have implemented again the helper function will return a valid struct, the naming convention is get underscore name for the struct and the single argument that will be consumed is the global unique variable ID this one is really obvious and really easy to implement because this is just a type of the word in windows so basically we start by declaring the color ref variable we log the declaration by appending the variable ID to the name of the variable we initialize the variable by calling get underscore first underscore un32 this will basically grab unsigned integer from the first value store assign it to cr and then we log this value as it was assigned and return the struct to the caller which will be then passing this struct to the library call something a bit more interesting so for example this one is helper function for returning rectangle rectangle is a struct with four fields each one of them type long so what we do is basically pretty much the same apart from initializing each one of the fields separately and for each one of these initializations we log in our log file and in case study ffuzzing the windows VM what do we need to do in order to basically get a basically the VM in a decent state for our ffuzzer to run in an optimal way we start by installing Python 3.5 and then we have a bootstrap script that will set up the VM and do some general OS tweaks this includes installing wind debugger installing the Python module for couchDB communication in order to submit our crashes to the centralized database we perform some minor tweaks in the registry including disabling error reporting disabling updates etc we enable kernel memory dumps basically this is where we get the information about the crash we enable special pool for the module that we're ffuzzing the for the kernel mode driver that we're ffuzzing which in this case is wind32k.sys a special pool is basically the equivalent of page keep in kernel land and a special pool will make it a lot easier to detect use after free vones, double free and general pool corruptions as well so it's very important to enable this and the last thing and obvious thing is to schedule the ffuzzer control script to start on logon and reboot the system upon rebooting the system the ffuzzer kicks in the first thing to do is look up the location for where we store the memory dumps so if there is a memory dump we wrap the memory dump we run bang analyze using katiexie we store this in a log file that we will later on be submitted we checked for a leftover ffuzzer lock from from a previous run and we basically assume the fact that this is the log file that caused the last besword we bundle everything together which is basically the ffuzzer lock the memory dump file and the output from bang analyze and we submit all of these all together to couchdb where couchdb will basically in couchdb we will be able to do some triaging and querying based on the crash there was pretty much about it when it comes to windows again we have done some stuff on macOSX and QNX QNX just to prove the concept that it actually works and the ffuzzer is more or less platform agnostic we haven't really spent too much time ffuzzing macOSX in QNX but we've got some again prototypes for it when it comes to system calls in other operating systems they basically follow the same calling convention which is system v AMD64 application binary interface and the object store for POSIX and UNIX operating systems will store file descriptors most of the time as opposed to handles and file descriptors are more or less similar to handles it is basically the most similar thing we can get to handles and for the crash detection we have both the same choices either attach a kernel debugger or rely on the operating system to get some useful information for us in the syslog this is just an example for a single function we're wrapping an IO kit library call it's very much similar to what we do for windows the only difference is that we don't have handles or windows specific helper functions we have IO kit helper functions that will return an IO kit object when it's needed again very much similar when it comes to syscalls on macOSX we're kind of lucky because the XNU system calls are all stored in a single file called syscall.master and this file can even be processed in an automated way to extract all of this system calls with their IDs and their arguments and basically turn this file into a collection of system calls that can later on be consumed by the framework some of the results James already mentioned we're getting some interesting crashes in word.e2k.sys primarily in windows 7 why windows 7? Well probably because most of our users are on windows 7 unfortunately when it comes to other operating systems again we're looking forward to basically spending more time on that the current implementation for macOSX specific and QNX specific modules is just a prototype to be fair. We have some crashes in hypervisors which is something that we never intended to find so this is basically just an annoying thing happening at the moment rather than something we can brag about we also found some interesting bugs in VMware tools and virtual boxcast additions basically these are bones that may potentially be used for escalating privileges because VMware tools is obviously running with an escalated context the sets of that we are using and this is just a set up for the stability runs we haven't even thought about scaling it at the moment mostly because we are satisfied with the results is host operating system hypervisor VMware workstation guest operating system win 764 bits and the VM specs is pretty modest to be fair just 2 gigs of RAM and a single CPU per VM this is just to recap the results from what James mentioned number of VM 16 stability run for 48 hours 65 crashes 13 of them unique and this is before we started blacklisting all of the system causing a lot of problems break down on the type of crashes we have 4 no pointer delays potentially exploitable win 7 fortunately for windows not exploitable on win 8 and win 10 we have some use after freeze 2 of them we have 4 pool buffer overflows basically pool corruptions and we have 3 under the category of miscellaneous basically 3 invalid reduxers violations we haven't properly 3 hours by now this is a breakdown on the crashes of the crashes based on the bug check ID the interesting thing here is to notice that a number of these crashes have been caught only thanks to special pool being enabled for the win32k.cs kernel mod driver so should you run without special pool you end up with at least half of these crashes further work what we can do to improve the framework and to improve the windows specific modules for example obviously we want to increase the coverage how can we increase the coverage the easiest thing and what I think is a very efficient way of increasing the coverage considering the current architecture is object tagging so if you remember in the object store we preserve a bunch of handles but these are handles to any kind of object so object tagging would basically involve adding another field in the BH handles truck and this field will specify the object type for the handle where this handle is pointing to so when we make a request to the object store we will be specifying the type of object that we are expecting to find on the other side of the handle we have well obviously we can implement more of these library calls 500 is a good number but there are so many of them we can implement experimental implementation for user mod callbacks based fuzzing this basically works at the moment but we had some problems with the logging so none of these results that I was talking about are with user mod callbacks enabled in our framework so once we get this working I expect even more crashes another thing is multi threading if you can imagine the lock file that we currently have is a huge lock file of C statements that are plugged into a main function and executed sequentially basically so this is a problem with multi threading all of these runs have been from a single threaded run of the fuzzer obviously we have to work out how to implement proper logging with multi threading at the same time and we can also look at some coverage feedback on CPU features so if you know about NCC's Triforce implementation well would it be possible to get something similar for Windows under miscellaneous we are always looking forward to improving the logging because basically it's just a really tedious and slow process of implementing each one of these library calls with the lock statements for each one of the C statements that we have in the file we haven't looked at handling all of this at all so basically if a hypervisor crush occurs these days we're just going to have to monitor the database and see that the number of crushes is dropping and then we've realized that hypervisor has been down for a few days test case reducer we have considered looking at C reduce this is a program which is basically a test case reducer, language a word test case reducer that can successfully reduce C files we haven't really implemented anything on top of that but the basic idea is that one VM will be reducing the test case will be feeding this test case to another VM, this second VM will be compiling and executing and will providing feedback back to the first VM which is constantly reducing the test case and just in general we definitely need to implement this and logging for the VM and ideally this logging should be hypervisor agnostic so basically this monitoring should be working on VMWire virtual box, keymuse, etc these are the people we want to thank these are all people who provided really valuable feedback and some useful ideas and information when we implemented the fuzzr and basically the core of the framework will be available online I think later next week as soon as we get back to the UK basically and keep an eye on sweet we'll be bragging about releasing the framework I guess if there's any questions I'm happy to take them at the cafe area because I'm being told we are running out of time but yeah, thanks guys


I also want to thank the organizers for organizing the session, giving me the opportunity to speak to her and to you today. The gradual advance of the Earnfield phenomenon has been discussed in detail, and various reasons for this has been offered. The spreading homogenization during this period is often attributed to increase connectivity and mobility. The reasons behind this, though, are hard to grasp. And reason, traditional, sorry, I'm a little loose, traditional archaeological techniques have reached the limits in doing so. But due to recent advances in chemical and biochemical analysis, we can now rely on a list on different techniques in ascertaining mobility and connectivity. But sadly, the outcomes are rarely sufficiently integrated. And following talk, I want to give an overview of an interdisciplinary approach I use for assessing mobility and connectivity and the lower Tryzen Valley in the cemetery of Inserstorf for my PhD thesis. And by mobility and connectivity, I do not only mean the mobility of people, but also that of objects, that of ideas, that of beliefs, and also that of knowledge on the individual level, but also on the level of communities. Just to give you a short overview of the cemetery I'm working on, it's situated in a lower Tryzen Valley, close to the Danube confluence, and a construction of a motorway there, demand a huge amount of gravel, which resulted in large-scale rescue excavations, and led the Tryzen Valley to become one of the best archaeological investigated areas in Austria. You can see all the sites that have been uncovered. The heritage department conducts the excavations there. Here's just a few impressions of that. And yeah, the cemetery contained 270 different graves, which is the largest early-earthed cemetery in the eastern Austria we have, including 21 graves with more than one individual. So the graves are either long rectangular. We are considered these to be the oldest graves, or round two irregular, which are considered the younger graves. Most of the graves contained earned burials, but some scattered cremation graves were also recorded. Large parts of the center, the rims, were removed during gravel extractions in case you wondered of the strange shape of the cemetery. And in the southwestern area, it is overlaid by a cemetery of the Latine period. As I said, the cemetery is situated close to the Tryzen then you have Confluence, but then you provide the Bowerful West-East access, and the Tryzen supplies access to the Alpine foothills with the natural resources there. And given that location and the assessment of the grave goods, a number of different kinds of mobility can be expected, like long-term seasonal immigration, residents' changeable marriage, travel, trade, or just social visits. And when you consider that, there are some questions that arise, like where do foreign influences come from? How strong are they compared to one another? How well is in the stock situated compared to other cemeteries? Which kinds of mobility can be detected? How can they be linked to certain identities? And what does this tell us about the communities? And how does a geographical setting influence connectivity and mobility there? And how to answer that question, there are a few techniques I rely on. And well, ascribing a specific material culture to a specific ethnic group is definitely outdated today, and definitely what I mean when I say I search for foreign goods. When I search for foreign goods, I basically mean goods which should not usually occur within the context of the specific material culture of the specific site. This is a technique that is solely based on the artifacts, and so it relates to the finds only. However, objects do not move without the help of people. It's just not necessary that the people, the objects, were found with that were responsible for moving them. They might not even be really foreign. They might be locally made, and even the idea of the object travels. This is an approach that has been used frequently in previous times, but has been neglected in recent years due to the upcoming of more modern techniques. But I would argue that there is still a lot of value to be found there, especially if complemented by other techniques. The basis for this is a well-defined local range of material culture, which is why I am at this point re-evaluating the around-field culture in the region of the Lower Trison Valley. Here on the upper map, you can see all the first sites that have been uncovered there. Culturally, the cemetery has been attributed to the Bayer Dorf-Wellerzitz group, spreading in eastern Austria, western Hungary, western Slovakia, and southern Moravia. And in the Dorf is situated at the westernmost edges of this area. So the only really foreign goods I'm going to be able to find, or I'm finding at the moment, are western goods. Because in the eastern area of this whole cultural complex, there's just the same stuff to be found. On the individual level, social status analysis provides the means of interlinking different kinds of mobility with the social stratification represented in the cemetery, if you presume that the cremation mode and the burial mode represent the social status of a person. While I was working on this, I realized that while I was working on the cultural chronological, but also on the social status analysis, I realized that a detailed insight is hard to get due to the poor preservation of many findings caused by the fire during cremation, the economical processes while being interred, or the rough method of excavation. And furthermore, the distinction between those differences is harder to get than it first seems. But exactly the differences, burned on a fire, only placed in a grave, or a dual function, could give us insights in how a person was perceived and how the cremation ritual developed and changed over time. And therefore, it gives us a chance to understand the underlying societies better. Therefore, I started a series of experimental cremations in 2018 to see which conditions and how they alter specific artifacts and see if we can link specific alterations to specific utilizations during the rituals. So as for the level of communities, thank you for explaining network analysis already so I don't have to do this. Although I use it a little differently, for me it provides the means of exploring interaction, but not necessarily movement as such. For me it provides the means of assessing the degree of interaction by connecting nodes, for in my case, cemeteries, through various attributes, in my case, cemetery structure, great structure, great ritual and great goods, and expressing them in statistical terms. So far, the computer network shows only a very patchy and biased picture. This is why I put it so small in the upper left corner so you can't see too good, because at the moment it tells us nearly nothing, because here you can see all on this map are all the cemeteries I've taken into consideration. And then the following maps, they're all in yellow, are all the cemeteries where some kind of data is missing. So, and if you would cancel all these out, there would only be in the stop left. So, there's, at the moment, a very huge bias towards in the stop, but this is mostly due to the size and the data I have. Chemically assessing the provenance and the characteristics of artifacts gives us additional data that can be checked to both of the ecological results and refine the interpretation of these artifacts. As for the bronze artifacts, trace elements analysis main purpose is chemical composition. It's shown as the chemical composition of the artifacts. And the foundation here for is the assumption that artifacts made from the same or deposit share a chemical composition of trace elements. And even if we cannot match the artifacts to a specific or deposit, we may be able to identify workshops or units of production such as artifacts made from the same mixed sources. Second let, as a analysis main purpose, is origin determination based on mainly the same reasons. It is thought that artifacts made from a or deposit shared the same, that is, appropriation. However, you have to be aware that ratios may strongly vary within an or deposit and that some deposits may share the same ratios. Sadly for the lower Trisen Valley, there is no comparable data available at the moment, but we have a good grasp on the Tyrolian and Mitterfagration and on the Slovakian region and an ongoing study will hopefully give insight on the Eastern Alpine Samaritan region. Additionally, the analysis of the stone material can give us more insight about raw material procuration and found that it is in the store seem to have been obtained from the southern Morave in the region. Combining the results of these analysis, there's a lot of questions on where the raw material came from and how and will reveal to which degree metal circulation, raw material appropriation was important as a trigger of travel in general and how this impacted the community or communities. Whereas the described techniques, primarily tackle objects as proxies, new biochemical approaches, give us the means of targeting human mobility itself and therefore rely to migration. Since we are working with cremated remains as we all know, we don't have to deal with genetics, but strontium isotope analysis has been successfully applied for years now and more or less recent research has shown that cremated remains have some advantages over non-cremated remains when it comes to strontium isotope analysis. Because we can measure every bone we want to and since the human bone remodels during lifetime it is thought to reflect the final years of one's life. However, it has been pointed out that the different bones vary in the time it takes them to remodel and therefore we can draw conclusions about which age most of the migration had happened by just supposing different kinds of strontium isotope ratios measured from different parts of the body. And since the results relate directly to migration they can highlight gender, age and status relate to migration patterns and can tell us whether some objects move together with people or not indicating migrated people or travel or trade or just other forms of distribution. So far we have analyzed 120 samples out of 104 individuals and mathematically only two outliers could be identified that that is a chance more, but here we have to wait to still ongoing environmental sampling. We did this together with Christopher and his team. Yeah, one of the outliers I wanted to show you is from grave 29 of my cemetery because it's actually this outlier here and it was a juvenile individual which was associated together with a bronze casting mold which might indicate metal related travel, metal related migration, maybe some form of knowledge transform, maybe some form of apprenticeship, yeah. All by themselves these methods provide only a very restricted insight and a very narrow view on mobility and connectivity and they all have their restrictions and advantages. On Thursday Colin Renfrew raised the question whether we see different kinds of mobility, large scale migration in the early and the advance of the bronze age and travel and trade in the evolved bronze age. I would say no or we don't know at this point simply a question about which methods have been applied because for the early bronze ages and for late neolithic lots of strontium isotope catheter and genetic catheter exist and for the later bronzes major much metal analysis has been done but with the strontium isotopes and with genetics you're never going to be able to target trade and with the metal analysis you're never going to be able to pinpoint migration as such. With both of them you're never going to be able to really target knowledge trends for and influencing short time travel. So therefore the point I really want to stress is here that we are also not really only interested in who went where, killed of all the man, made it with the merman and superimposed a new culture neither are we only interested in which stuff was brought where. What we're really interested in is how the dynamics of the society work, how interaction affects individuals and communities and how in turn they affect interaction in order to understand the resulting continuities and discontinuities better. So therefore we have to compare, interrelate and interweave different kinds of data to draw a more broad picture and watch what kind of mobility and connectivity and interaction took place for my case to understand the cemetery in the stuff better but also the whole environmental phenomenon. Thank you. Thank you. Thank you.