 Okay, so hello everyone, my name is Bartos Zatter, I'm from Samsung Mobile Security Team and today I'd like to tell you about our tool for memory serialization of the Linux kernel variables, which we call Kflat. So few words by myself, I spent more than 15 years in various jobs in mobile product development and in recent years I've worked with security engineers to perform the verification of the Linux kernel code for mobile devices and and today with me is Paweł, one of the security engineers who actually wrote the Kflat tool with me and few words why we did that, so we know every day work our main job is to find, analyze and debug software problems in the Linux kernel and having known what's going on inside the system can be very helpful for this analysis and memory dumps comes handy at that task but the problem is that the existing tools usually provide a very large dumps, most likely the entire VM and you cannot easily relate the content of the dump with the corresponding source code structure, so this is what we needed for one of our tools so that's why we developed it and now we want to present it to you. So how this talk will look like, so Paweł will start and we'll tell you what is Kflat, how it works, how to use it and we'll give you some interesting implementation details and I will take over in the second part to show you how Kflat could be used to actually help finding software problems in the Linux kernel, so I hope you will enjoy this presentation and Paweł let's get started. Thank you Bertosz, so Kflat short for kernel flattening is our open source tool for, okay sure thanks, so it's our open source tool for serializing Linux kernel variables or function parameters and restoring them in any application especially in C user space applications so what Kflat does, it hooks into some target kernel function, obtains the reference to interesting forest variable, copies content and follow all the pointers in this dump area that it could find, it sounds a bit simple just a few mem copies and we're done but there's a bit more to it since most of the kernel structures are huge, for instance very commonly used structured task struct has more than 3000 direct dependencies and by direct I mean anything except void pointers, list heads, container ofs etc, so basically if you would like to copy task struct into a new C project we need to copy 3000 other structures as well for code just to compile so this is the scale we're dealing here with, also there are these in specific kernel constructions like list head, container of, they have to be handled accordingly but once we deal with all these aspects we end up with easy to use and portable memory dump, such memory dump can be then loaded or mapped into a new application, into new address, into new virtual address space and used like any other C memory, what we can use it for, we can use it for fuzzing initialization for instance, we can dump some memory from normal running system and use it as an initial corpus for fuzzer, we can use it for debugging, we can dump some internal kernel structures and then view them in user space just like with kgdb, except that we don't have to recompile the whole kernel with config kgdb or use any additional hardware, finally we can use it for info or logs, stats, gathering, we can extract new metrics from the kernel by accessing its internal structures and viewing them in user space, so how kflat works, we call this process of serialization flattening because what kflat does, it flattens some huge memory into a single continuous blob, let's take a look at the simple example, on the left we have two structures, struct A with a pointer to struct B and struct B with pointer to some string and pointer back to struct A, on the right we have an example representation of these two structures in the memory, well when kflat starts its journey in this example from structure A, it collects all the memory regions it could find by following the pointers, then it sorts them in ascending orders and finally flattens them into a single continuous blob, then it replaces all the pointers in this blob with offsets, and that way we end up with small and portable easy to move and save memory representation. When we would like to restore this memory in user space, all we do is we load this into a new address space at some address x and we fix all the pointers, all the offsets that are stored in this image with pointers in this new address space, finally we obtain a reference to our initial structure, so we have some entry points to this dump memory, in such way we end up with the same memory in your application that can be used like any other C memory, but how kflat knows where the pointers are in the structures, this is a quite tricky task, since in C we have no run type type information like in C++ or Golang or other higher level languages, also in C pointers are a bit imprecise, we can have a pointer to void that basically can point to anything, we can have a pointer to integer that can point to a single integer or an array of integers, basically in C pointers are just numbers that can point to anything and can be anywhere in the structure, so in kflat we use recypes, so-called kflat recypes, they are the representation of kflat structures, sorry they are the representation of structures used by kflat to precisely dump the target memory, to know where all the pointers are, moving back to our previous example for these two structures the kflat recypes looks like that, we have a structure A, we field PB that has a pointer to structure, that is the pointer to structure B, we have a structure B that has a pointer to string in field S and also a pointer to structure A in field PA, that way we can kflat can precisely dump the memory and preserve all its layout, let's take a look at a bit more complicated example being an interval tree, let's imagine we create internal interval tree and push into it all the virtual memory regions that are allocated in the kernel, under the hood such interval tree would be implemented using red black trees, just like just it could be seen on the left and right side of the slide and by using a few lines of code kflat can dump this memory like without any problem, for the interval tree having 600,000 intervals the produced image have something around 32 megabytes, so it's quite portable and the flattening process takes just a few milliseconds, so it's almost instantaneous, now how the kflat works under the sheet, from the very beginning our goal was to use kflat on embedded systems like smartphones, smartwatches, android devices or iot devices and that's why we implemented kflat as loadable kernel module, that way we don't need to rebuild the whole kernel image every time we want to change something, we can simply build kflat push it onto the target device and load into the kernel, also kflat resides that describes all these structures layouts are built as kernel modules as well, so we can hot plug them into the running system, once we load it kflat into our system we can start dumping memory, we first arm kflat onto our target structure and target function and invoke this function somehow from the user space, for instance by calling syscall or sending something in packet or maybe performing hardware interaction, using kprop subsystems kflat hooked into the function and intercepts its call, then it invokes its flattening engine, at this point kflat follows the provided recipe and dumps the memory from the context of this function, so we have an access to stack variables, globals, heap, basically we see kernel just like this function would see, finally optionally if user asks us to do so we skip function execution to avoid causing any side effects in the running systems, of course during this memory dump process some exceptional situations may arise with invalid pointers being the most common one, whenever kflat is dumping structure and following its pointers it can encounter null pointers, users' key pointers in case on kernel some input output memory and possibly white pointers, because for instance some filtering the structure is unused or uninitialized and kflat has to somehow detect all these types of the pointers and avoid causing kernel fault at any cost, we do this by kernel page type bewolking, we for each pointer the kflat encounters, we translate it from the virtual address space into physical address space using page maps just like normally CPU does and then check whether the physical address is pointing into the RAM memory, finally we check whether this RAM memory is readable to avoid to dump only the memory that is holding some data, not some code assembly that cannot that isn't portable in any way, that approach in contrary to relying to page fault handlers allows us to detect whether the target pointers point to RAM, to avoid dumping memory that is for instance mapped input output memory to which accesses could alter system state or even cause system crash, next kflat has to somehow handle data issues, many kernel structures are used concurrently and are synchronized by using some synchronization primitives for instance mutex's semaphore spin locks, kflat we usually cannot lock all of them since it would cause global system deadlock so what we do if we need it is a bit straightforward and brutal but we use the machine to basically freeze all other tasks in the system, with that we can create some memory snapshot from some moment of the kernel, if user needs to access the structure heavily used and wants to ensure that the memory is complete he can also specify the mutex is to be locked, next we have to handle somehow unknown array sizes, in kernel quite often you can see zero size arrays or pointers to some integers or some structures, these are of unknown size, it is not always obvious what is the size of these objects based solely on the static analysis of the code, so in kflat we also support extraction of allocation metadata from slap allocator, in cases when we are unsure of the target array size we ask slap allocator to provide us with the necessary information about allocation size and to dump the whole array of the objects, even if we don't know at the compare time what its size is, finally very common pattern in the kernel are function pointers embedded in the structures, for instance structure follow operations very commonly used in the kernel that is storing some function pointers to the handlers, in kflat we cannot obviously dump the targeted memory pointed by this pointer, since this is the assembly code that cannot be used on the other machine in new virtual other space, so kflat using calisthenics converts this function pointer into function name and saves it in our flattened image, then during the restoration we expect user to provide us a map that will convert this function names into some functionally equivalent functions in new system, in new other space, it can be some working function or it can be some simple step if this function it's equivalent is unavailable in new application, that way we can prevail function pointers in new other space and make them work just like they would in the kernel, so as we can see kflat is a bit tricky and somehow complicated, so what about some other approaches, well first of all as Bartos mentioned in the introduction we can try using virtual machine snapshots, basically run some kernel in the virtual machine and dump the whole machine, this approach has a few disadvantages, first of all it's not always easy to run target kernel or drivers in VM, especially if they are intended to be used on some specific proprietary SOC, also the whole snapshot of the virtual machine is time-consuming and resource-consuming, we will end up with for instance 8 gigabytes of memory, also this memory will be a whole RAM memory dump, so it's not easy to deduce where some structure starts or ends, for instance if you are interested in a very particular structure in kernel, it is not obvious where it is in this dump and an alternative approach is to blindly follow all the pointers, so we basically start somewhere in the kernel memory, we dump for instance a structure, look for everything that seems to be a pointer, we can validate them whether they are correct and then recursively follow everything we can find, well it's not always in this approach it's not always obvious what's the size of target memory, also it's not always easy to determine which pointers matters to us, for instance if we start dumping structure file we will then follow to the structure-tact-stract, we then by using list-head follow all the task-stract in the kernel and the task-stract also holds the pointers to virtual address spaces of the processes, so we will end up dumping visual address spaces of almost every processes in the system, so again we have no fine-grained access, in case of Kflat we can perform a memory dump of only structure and its parts that are interesting for us, our flattened image is very quick and easy to restore and also we can intercept kernel functions in vocations, so we can perform a memory dump from the perspective of some function, and finally our memory images directly represents kernel variables, so the very same code that used it in the kernel can then use it in other applications without any changes, so to sum up this part Kflat is built as a loadable kernel module, so it is very easy to use on embedded systems and can be easily loaded into running system, it provides instantaneous restoration, which is perfect for fuzzing and other use cases, and also it allows us to relate the memory dump with original structure of the code, so we don't have to use any additional API, we can just treat this restored memory like any other C memory, and now I would like to hand over to Bartosz who will talk about use cases of Kflat and the automatic generation of Kflat Recypes that are necessary to perform these memory dumps. Thank you Paul, okay so how could we use to test the Linux kernel right, so actually we ask ourselves the opposite question, what kind of tools could we implement or integrate that could help us finding software problems in the Linux kernel, and one of the answers was the Auto of Target project, so let me quickly introduce you to the Auto of Target project, so imagine you have to test a piece of software that is otherwise very difficult to test, so you might have some WLAN driver, you might have some parser embedded deeply into your WLAN driver, and in order to test it you have to set up the connection and send the messages over the air, so you have natural limitation in the throughput, and so if you are employing some fuzzing it would be very slow, so we're looking for some alternatives, and one of them could be off-target testing, so what is this, so we just extract the parser code from your WLAN driver and test it, I mean compile it on your development machine, and then just create the executable and just feed the messages to the your parser code to this executable, so in that scenario you have all the development tools available for your disposal, so you could use a GDB, you could embed coverage information, you could use fuzzer, sanitizers, valgrind, you could even use symbolic execution, etc. Of course we assume that the parser doesn't depend on the hardware very much, so it doesn't write to the CPU registers directly, just a portable C code that shuffles around data between buffers, yeah, so how to create the off target, so you extract the main parser function and try to compile it, and probably it will fail because there are missing dependencies, so what you do is just pull more code and some missing type structures, some missing type definitions, some missing functions, missing global variables, etc., and try to compile it again, and you probably have to do it many many times until it finally compiles, so as you can see it's a quite painstaking job to do this, so that's why the AOT project was born, to solve these problems you can see there's an automating in the name, so it actually extracts the compilable off target from some bigger system in an automatic fashion, so you can see, if you're interested you can see the github page of this tool or you can read the paper or see the talk from the CLE workshop last year, but the main question is how could this help us in finding software problems in the Linux kernel, right, so the main idea is, so maybe we could take the entry point to the kernel, so for example some IOCTL function or write em up etc., and just create off target from it, compile on your developing machine and just test it there, yeah, but there's a problem because when the kernel runs the IOCTL function, there is an entire kernel state available to it in this function, but when you just run it in your off target there isn't, right, so yeah, so you add off target, so of course the IOCT project provides some initialization mechanism, so there is some feature that it tries to initialize all the kernel structures in the off target using some lightweight static analysis, but it's not perfect and fuzzing can lead to some false positives, so another idea is to, how about when the kernel runs the IOCTL function, so we just save the entire kernel state used by this IOCTL using the k-flat tool and just dump it to the file and restore it in the off target, so you could imagine this whole process as just transferring the execution from the target to the host or developing machine or multiple instances of the developing machine at the point of this IOCTL function, okay, so the question is, so what is the kernel state used in this IOCTL function, so we have the function arguments like struct file here, it represents a lot of kernel state because it's quite a big structure, and we also have the global variables used in the code of our IOCTL function, so those are the two things that we need to save and how to do it, which is insert the k-pub injection at the entry of this IOCTL function and we can just run, execute the k-flat resypes that do all this work, so if you need to extract the address of the global variables, we just can consult the kiosk sims our kernel symbol table, so initializing the part of the kernel state in the off target was one of the possible usages of k-flat productively and another idea would be some extracting some debug information from the running system or getting some periodic snapshots of data for the tracing purposes, so here is an example of a simple resype that is used to dump the task struct information from all the processes in the system, actually this is a full resype that is needed to do this, and it follows the task dependency in the task struct, and yes, there's still a lot of non-pointer members in the task struct that can provide you with some information, and below is an example of a user space application that actually reads the dump and just prints some information from this dump, but it can do whatever it needs with that, so these were some examples how k-flat could be used to actually help finding and analyzing some of the problems in the Linux kernel, I hope and I'm sure some of you can find either by the way so utilizing that, and right now I want to discuss preparation of the resypes for the proper k-flat operation for the Linux kernel structures, yeah so what's the deal here, so the k-flat dump is as good as the resypes used to describe the format of the data to be saved, so we have a problem here because there's quite a lot of kernel structures that we would need to handle, so for example in the Android common kernel for the x86 there's around 15,000 interesting struc types that we would need to handle, and what I mean by interesting is that some non-animals or type depth struct types used in some functions or some global variables, so and even though half of it is trivial meaning there is no pointer data inside those structures, we still need to handle around 23,000 pointer members and write the resypes for them, so the question is maybe you could generate those resypes right, and the problem is it's a very difficult problem to solve in general because you might encounter some edge cases that would require you to know the code perfectly well in order to write the proper resypes, so this is quite difficult to automate, so maybe you could take another approach like maybe you could generate all the resypes which work most of the times and just handle the edge cases by hand, so now we are thinking about writing the resypes generator, but in order for this task to be successful we would need to have some kernel type information available to you because you just want to write the application, you don't want to write the parser itself, but actually we have it because last year I spoke at the Linux Security Summit in North America about the Code-Aware Services project and especially the function type database part of it, the FTDB, so you can see the YouTube video here if you're interested, but the main point here is that we have this clang processor that extracts some interesting information from the C source code like type information and saves it in some intermediate format easily accessible by application like in a JSON file, so now we have this JSON file so we can just start writing application, our resype generator, so let me show you what kind of problems you could encounter while trying to do this, so the first problem is that as I mentioned already we have a lot of structure members that we need to handle, so we have a lot of potential for the edge cases we might encounter, so we can manage that by just focusing only on the members that we are interested in, so for example in our off-target that would be the members which are used in the off-target code, so for example here we have this FBO function and only the FINOD member of the struct file of the argument file is actually used, so maybe you can get away with just writing the resypes only for this resype only for this member, and the data that backups this approach is something like in our experiments with generating 1000 off-targets for the Linux color entry points and when we focus only on the used members, on average there's around only 10% of the members actually used of all the defined members in the source code of the average off-target, yes so another set of problems is related to the polymorphic nature of the structure members, so for example we have this point pointer member here, so where does this actually point to right, is it a struct B or maybe some RI of integers etc, so we don't know that, so what we can do is we just implement some kind of static analysis of the code and we just look for all the expressions where this void pointer member was actually used, and maybe we can deduce the type it points to based on this analysis, so it might be some, we can analyze the assignment expressions, some initialization, direct casts, passing the function, retrofer function etc, so yeah of course this static analysis can give you some ambiguous results and in that case you would need to intervene manually, but in a lot of cases it actually gives you the one proper type where it points to, another problem const, I mean the character pointers, is it pointing to a C string like terminated by zero byte or is pointing to some RI of characters of specified size right, so what we can do is we can just take our member and check whether it was passed to some functions that we know takes the C string as an argument like Stirland here, if it does so we can assume we can deduce that our member is the actual C string because otherwise our original counter code would fail when executed and here the pk is it pointing to a single element of this struct k or just this RI of elements of struct k right, what do we can do, we can just check all the reference expressions of this our member pk and check whether there's a, the reference offset different than zero used in any of these expressions, if not so we can assume that deduce that pk is pointing to a single element of the potential RI right, and the final example actually my favorite example is the brilliant pattern of the Linux kernel list implementation, so what we got here is we have a list of the Linux kernel elements linked together using the list hat objects right, so we have the two challenges here, the first challenge is when we have list hat member is it ahead of a list right meaning pointing to the first and the last element of this list but not being actually the list element or we have the anchor meaning it's embedded in some bigger structure and and this structure is the actual list element, and the second challenge is we have to conclude what is the actual list element type right because we have only the anchor, so how to find the hats, so maybe you can just check all the invocations of the Linux kernel list API and just to match the arguments passed to these functions with the parameters that takes the hat, so for example here we have the lh2 member which is passed to the list up tail as a second argument so we can see in the API reference of the kernel the second argument is a hat, so we can conclude that lh2 is the actual hat of the list and how to find out what is the actual type of the list element, so again we look for some function in the list kernel API that's actually extract the element type from the anchor, so for example here is the list for each entry marker which calls the container off under the hood, and this is actually what we're looking for because the second argument to the container off is the actual list element type, so when we have the hat and we have the list element type we can just walk the entire list one by one and just dump it to the, by using the the recypes, okay so so in summary we can apply some static analysis to improve the generation of the recypes for the Linux kernel structures, and one more thing I want to tell you about the recypes is the potential problems that you may encounter while trying to compile those recypes because as you can see here is the reminder of the recypes from the beginning of this simple example from beginning of this presentation, and as you can see here the recypes actually references the members by name, so in that case you would need to include the full type definition of the structure in order to compile because the compiler needs to compute all the offsets, so it might be a problem when you're writing a recype for a structure which is defined privately in some C file, right, because you cannot easily include the C file in your code, so what K-flat, how K-flat helps you with that, it provides you with a family of some called self-contained familiar recypes where it is your job to provide all the offsets of the members in your structure and also the size of the structure, so in that case you don't need to include the type definition of the structure you're writing recypes for, but of course the minus side is that you need to compute all the offsets by hand, but this is mainly dedicated for the recype generator, so probably it wouldn't matter, wouldn't matter to you, and finally even if you have this very well-working recype generator backed up with some advanced static analysis, there still might be cases where it won't work properly like here. Are we using the void pointer member here, so we have to follow the dependency or we just using the unsigned long value and we just enough to copy the data, right, the information which member of this union is currently used can be spread around different structures and might not be easier to compute, so these kinds of cases of problems would probably require some insight and help by some people who are responsible for the specific model here and also even if you write a recype for your own type, your own structure in your own driver, you still can end up having some common kernel structures in the dependencies, so you could end up writing the recypes for a common kernel structures again and again, so what will be highly beneficial here is to if we have some this kind of library of K-flat recypes written or reviewed by experts for common kernel structures which could we just include and just use in our quote when we're writing recypes for our structures, and we're almost there. Everything we said about this so far about the serialization of the variables was done inside the kernel, right, but the same principles, the same algorithm could be applied to the user space memory as well, right, so we could easily extend K-flat to serialize the variables from the user space process, so for example you might have some user space process which actually reads or computes a lot of data before it's actually start doing something useful, like a very good example of that is some very big build system which reads a lot of make parses, reads and parses a lot of make files before it actually gives you some very small incremental build, so what could we do here is just we could prepare the snapshot in the memory of all the parsed make files, save it to the file, right, and again when we run the build again and assuming the make files didn't change we could just read those in a matter of milliseconds, so to summarize that K-flat can serialize a Linux kernel variables with their dependencies, so it's built as a lot of our kernel modules so it's easy to use even on the embedded systems and it can restore image very quickly and yeah it can relate the content of the dump with the corresponding source code structures so it can be used as a state utilization for the Linux kernel code, so you have to write the recypes to make a proper dump but you can generate those recypes but you might encounter edge cases that you would need to fix by hand and it can be easily extended to the user space and you are the one who can find a new ways of using it, so thank you very much for your attention, the feedback is highly appreciated, this is open source tools so there's a github repository you might check, so just file an issue or create peer or just write an email with any critique that you find appropriate and if you have any questions you can try to answer them now or just you can approach us at any point during this conference, so I hope you've enjoyed this presentation and see you next time. So thanks that was very interesting, what I, as a you know distro guy I sometimes end up debugging a crash dump of customers crashed kernel and there is a kdump file infrastructure that creates the full dump because when you're crashed already you can just take the full dump so I wouldn't like apply your complete, your complete, but what was very interesting to me is the way you can classify lots of the pointers automatically because often when I debug a crash dump there's some address that's somehow involved in the issue and in the crash tool I can see so what is this address and it will tell me oh this comes from this slab cache so I know it's a dentary and that's fine but many of the allocations are from the kmaloc caches which can be anybody doing that and I don't know the type and I have to somehow try to search if that pointer is used if it appears in some other structure that from that I can derive what it is so what you're presenting the way how you automatically you know get this type information I think it could be applied also to classify many of these kmaloc objects in in a full crash dump so that so that would be very interesting to try I tried it once as a quick project but I quickly ran into the issue that I would have to do a lot of manual work and I don't have many of the type informations and now you tell me that there's this ceiling-based thing that can infer it by static analysis so that looks very useful thanks yes thank you that was one of our one of our main goal to deduce the types of the pointers since we are performing this partial dump so we have to you know dump all of the structures yeah so we have to know what the pointers are so we are grateful that we find this interesting and thank you and maybe another question is how would you compare your approach with what dragon is doing dragon drgn it's all something like a debugger for the kernel yeah actually currently I'm not familiar with dragon so I cannot compare it right now okay maybe if you looked at it it would also give some ideas how to improve your thing because it also tries to look at the kernel without stopping it and it uses the proc k core mechanism so it doesn't have to be a kernel module and you can write python scripts that tell it what to do like the kernel specific knowledge you encode in the python script so you can tell it also look at this truck look at that truck so so you can kind of if your goal is to analyze some specific thing you don't have to extract all the data outside you can do it right using the python script but I I don't think it can hook into the k probe and three points like your approach can do so yeah but you can look at it whether there's thank you for suggestion definitely we check this out yeah here the first row so in my previous life just working for a virtualization company we'd get crush dumps I guess similar to yours of different types of Linux distributions and we try to figure out if this was the virtualization tool was the hardware or it was the the kernel itself and that would put us in a tricky spot for certain certain structures in in in the kernel so I'm interested quite a lot in your mechanism of resolving the pointers again that's a very useful thing and not so much the actual serialization under great writing elsewhere although you know maybe the whole the tool is together and maybe we can just use the the pointer resolution part of it would it be possible to take the basically the pointer resolution components and turn it into something like either a standalone tool that reads memory regions like you know symbols or just memory regions and gives us a separate list to use like the symbol list or even a plugin into a gdb yeah sure our the static analysis tool is already quite a separate tool it produces some intermediate representation of the structure so it should be possible to like apply it into gdb so that you can follow the pointers in it like resolve in gdb what this pointer is yes and what is for instance some void pointer pointing to in this current context but the very important part is that most of this applies to some very specific context of the kernel so basically we perform the static analysis from some function for some function and we know that these void pointers point to something in this particular context for instance if you've got field private data in structure file depending on the driver it will point to something else so in case of your core dump you have to somehow know where the structure was yes in both drivers so you can provide our tool where it should start looking from in the static analysis but apart from that yes it should be possible to apply in such scenario yeah and the actual recipe generator and the static analyzer which is a part of the recipe generator is actual a python script as well so it just takes the information from this ftdb database it's just a json file generally and just reads this information and tries to make this analysis based on that so we just as you might call it a simple python application we just reads json and tries to conclude some information from this representation of the source code in this json so yeah it's it can be easily used in some other context too so my question is more related to do with test of code coverage testing when your your job is to make sure that all your test cases cover code but like something like gcov can't it's it's hard to use that to tell am i covering lines of code in gcov itself because that's running on the system so is there any way not quite sure how to phrase the question but is there any way you could use something like this to sort of subtract out what you don't want and then show coverage of what's what remains so we would like to dump partial memory yes and yeah sure we can perform some partial memories realization or create partial recives and i believe you can fit it into this gcov if it is in the same format but yeah in general key that is fine grained tool so it can operate on the pointers that you instructed to follow so we can skip some pointers that you are not interested in in it so the actual recives is telling the engine for example we have five pointers in the structure so their side is telling okay this point this pointer points to strike b so just you you know this is struck b so dump this as a struck b right so you can choose which of the members pointer members you you just pick up so you can just pick one of them or you just don't pick anything so in the memory dump you will have the original pointers values right or but if you just pick this right pick this member right were types for it so then follow it follows this dependency and in the dump it produces you will have in on the other hand when you restore the image that you will have the proper pointer in the user space so you can just pick any member that you want or you can just don't begin it so it then it will not follow them thank you for the talk contains a lot of interesting ideas i have some practical question do you know maybe like do you have maybe some examples how kflat helped to solve your some issues or find some bugs in like in real life so actually the main idea is that we presented it's something like initialization initialization of the kernel state inside the off target so the main idea is to just take the entry point to the kernel and generate off target for it and we just want to test it on your development machine so we don't want you know to make run fuzzing on the target we just want to run fuzzing of this function extracted from this target like mobile device and just compiled on your development machine a big server the host machine big server and just make a fuzzing there and yeah and as i mentioned there's a problem with the initialization of the state which this off target code uses because original kernel code have the entire full kernel state available but in the off target there isn't so we have to somehow initialize those structures in the off target so this is actually the main usage that we currently are using for initializing this off target code from the linux extracted from the linux yeah so this is we don't have any other examples apart from extracting some debug information from the kernel as well which can be easy but more usages are up to to you know just finding out another usage of this tool right okay thank you now we have better understanding like how it's used thank you very much i think it's pretty it could be very useful to debug kernel code but you also mentioned in your talk it could be used also for in the user space then um i thought about that and i realized this solution could could only work for like a C language because um when you calculate the oversight or choose back to the the owner it's if there if there any additional information like like java there's some metadata about the object will it work yeah you are exactly right this works only for the C code yes okay because yeah because we have to write the rest types for the C kernel structures and this engine supports only the the C code structures currently some some po d plane of data structures so we don't suffer the C++ at least so far yeah but i don't think it would uh go go farther than the C and it's potentially C++ so yes it's only for the you know the C structures from the C code yeah do you know i don't know rast because i know kernel is start with using rast in do you think or because i don't know rast do you think that's also working for rast we don't know rast either okay thank you so thank you very much for your attention and if there are any more questions we will be somewhere around this conference yeah thank you