 Hey, guys. Thank you for coming to my talk. My name is Ryan O'Neill. My talk, revolutionizing Elf binary patching with Shiva. Let me introduce myself. My name is Ryan O'Neill. I'm also the author of the book Learning Linux Binary Analysis, which is a book on elf hacking and related topics. I've published in a lot of journals over the years, different hacker journals, Frack, Parker GTFO, VX7, Temp Out, and I'm also the founder of bitlackies.org, which is where I published a lot of my independent research for many years, up until about 2019, still up. I'm also the founder of Arcana Research, Computer Security Research and Development. This is actually this website where you can read more about Shiva, ArcanaResearch.io, and ArcanaTechnologies.io, which is a Linux threat detection technology for detecting various types of threats within elf artifacts. Before I get too deep into the talk, I want to take a moment to talk about the DARPA AMP program, since Shiva was in part born out of this program. This is a really unique program created by Sergey Bratis. It's the assured micro-patching program by DARPA. And this program is really cool. It's all about taking some brilliant creative minds who want to raise the state of the art in reverse engineering technologies and elf binary patching technologies. There's also an effort to be able to do formal verification of these patches. So after the patch is installed, can it be called safe? So there's a number of different facets to the project. And throughout the number of different performers, there's quite a number of CPU architectures that are being targeted right now, although I'm only specifically talking about my project today. But just the AMP program as a whole is really cool. So what is Shiva? So Shiva is a state of the art binary patching solution for elf. It's essentially a custom dynamic linker that's been highly specialized to load and relocate object files and transform the program at runtime. I've written a lot of linkers and loaders over the years, from computer viruses to kernel rootkits to all kinds of things, binary protectors that require different types of custom linkers and loaders. And this is definitely the pinnacle of my research after about 16 or 17 years of elf binary hacking. So what makes Shiva special? So Shiva has innovated quite a number of different new linking concepts. So the elf ABI has been extended to support more advanced linking and relocation operations that allow for program transformation at runtime. And Shiva's one of its primary goals is to make patching binaries approachable, meaning you can do it in C, almost just like you'd program anything else, trying to bridge the gap between the developer and the reverse engineer, because patching binaries is often clunky and difficult. Shiva allows developers to write nuanced patches with quite a bit of ease. So how can Shiva help you? So if you're an organization or a company, generally speaking, there's usually legacy software that no longer has source code, and a bug comes up, whether it's a security vulnerability or some kind of other bug, how does one fix that if there's no longer source code? And oftentimes a team of people might get together to try to fix a simple bug, and it's clunky. And there's no like development workflow for that that's really been put into our industry yet. So from a hacker's perspective, Shiva can do all kinds of things as well. It's an advanced instrumentation engine. You can use it to create black box fuzzing harnesses. I used it to fuzz the dynamic linker, one dynamic linker fuzzing another dynamic linker. But I can't really get through a lot of the stuff I want to get through today. So I'm going to blast through these slides. Unfortunately, a little quicker than I might want. So the origins of Shiva, about three and a half, four years ago, I had an itch to write a custom elf interpreter. Everybody here know what an elf interpreter is? Basically, usually the dynamic linker. But writing an elf interpreter is an interesting thought because, well, there's a lot of innovative concepts that can be ignited through that. And so this led to a concept called interpreter chaining, where I chained two dynamic linkers together into the same process image, my custom dynamic linker, which was evil, and then the real dynamic linker. My evil dynamic linker loaded a modular relocatable object virus into memory. And so this was actually my first implementation of a custom dynamic linker for elf or a custom elf interpreter. And you can actually read that algorithm for interpreter chaining and the whole virus and everything is published in temp out issue two article six there. And this, you know, modular elf virus loader interpreter ultimately loaded or ultimately morphed into the first version of Shiva, which was originally for x8664. I actually gave a talk about it a year ago, but it's a completely different beast than what I'm talking about today. But just giving you a little history there. And so the original Shiva was for loading elf micro programs. So it was a custom dynamic linker that allowed you to load elf micro programs to implement security features and such into the process address space like control flow integrity hardening or whatever. You could do a lot with it. It was an instrumentation dream toy for a reverse engineer. And that's still available actually just open source that today. We're going to get into this in a moment here. But the current version of Shiva is Shiva alpha version 0.11. And it was forked off that original version. So just to clarify, and it was heavily modified to meet the requirements and needs of the DARPA amp program, specifically NASA. And so, but with that said, it's, I'm not going to get too far ahead actually. So let me stick with the slide. So rewind 25 years. Who was originally trying to patch elf binaries? And for what purpose? And this brings us to the awesome era of early Unix virus research and Sylvia Caesar, who is a good friend of mine and mentor, published this research, you know, through about 97 to 99 this very early elf research. Unix and elf parasites in 1998 and a number of other papers I could list. But you have to understand at the time this was super esoteric stuff. Nobody was doing this in 98. Only what elf was elf. But I saw that paper when I was 15. And it definitely enamored me compelled me into wanting to work on that stuff. But yeah, just a ton of other research came after this by various underground hackers and researchers, which we'll talk a little bit about. But you know, it brings us to the concept of elf virus technology. It's really the same thing as elf instrumentation coming from somebody who's written a number of computer viruses for elf. The programmatic techniques that go into it are very much the same as instrumenting a binary with any other code. It doesn't matter if it's a parasite, or if it's security code, point is you need to make room within the elf binary. Oftentimes, the techniques aren't trivial for restructuring a binary, depending on the technique, you know, tech segment padding infection, reverse text infection, it's all kinds of ways. And then that code has to be relinked in some way, whether it's through PLT hooks, inline hooks, relocation poisoning or some other means. Also, we know that of course, you know, hackers like to inject viruses into memory. So p trace is often used. And it's often used for just instrumentation in general, you look at many different technologies out there, Dynamo Rio, bunch of them use p trace, I've used p trace a bunch to instrument. But on the same token, you know, security technologies use this as well for injecting patches into memory or instrumenting memory like Valgrind does. In a way, she was kind of similar probably to Valgrind and how it works in terms of the just in time kind of aspect of it. Basically, all the elf research was coming out of the underground scene. In the late 90s and early 2000s, there were a few major players in that area. One of them was the gruck. The gruck designed the user land exec implementation, which is a user land function that can execute another program. So you don't have to use the exec v system call and trap into the kernel one user land program can execute another user land program. This has all kinds of insane uses. He was using it for anti forensics. I've used it for binary protectors. And now I'm using it for Shiva, because it's a loader. And so very, very important research by the gruck and he did other cool stuff too. And of course, we have mayhem, who was the chief editor of frack around the time. And he had this incredible erasy project, the elf reverse engineering software interface, which I really can't say enough about truly profound work, especially in 2002, just the sheer level of innovation and work that went into eras is impressive. And there's a number of other people that worked with mayhem on that project, other aspects of it, but very brilliant work and very influential. And then another really influential piece of work that came from the early underground, probably 1999 was Silvio's, he wrote a version of ins mod that could install a kernel module through dev K mem by handling all the relocations and stuff manually. And it was the first implementation I'd seen of a hacker writing a linker or a loader at the time, but it really seemed very profound to me. And so that's some really, so these are some real formative pieces of work that definitely inspired me over the years. And there's also some really interesting stuff that's come from the academic space in terms of elf binary patching. Firstly, what comes to mind is Katana, which is a door for wear, hot patching framework for Elf. And it was designed by Sergey Bratis and James Oakley. I think it was about 13 years ago. And a couple of really good white papers came out of it. Pebble, I don't know as much about, but I've kind of paid attention to it over the years on GitHub. And it's a it's a elf instrumentation framework. I think it's primarily used for software profiling, but it does some degree of function relocation. And then we have this really great research called Weird Machines and Elf by Rebecca Shapiro and Sergey Bratis. And this was I think there was even a talk at DEF CON maybe in 2011, but it was all about using the dynamic linkers relocation computations as a touring complete machine. So you can program the dynamic linker to do a lot and just through metadata, you know, relocations, whatever. And this is something Shiva does a lot. And so these are these are just Yeah, this is great stuff here. Take a look at some of the research tied to it. So you know, we could say Elf binary instrumentation is a double led sword. There's a lot to be learned from the hackers and the underground community who were first putting this information out before 25 years later rolls around and here we are needing to design advanced binary patching technologies. And Shiva has done that. But it's very much based in knowledge that I've had pre existing, you know, in the underground scene. And so we're like, okay, well, binary patching is pretty old goes all the way to back to computer viruses. But really, it goes back to the beginning of Elf, which became the Unix standard in 1995 executable format and for Unix Linux. And, you know, having been somebody who's done a lot of Elf binary hacking over the years, I put a lot of thought into this project. And I started, you know, looking at Elf and saying, really, it's already equipped mostly with what it needs. It's already equipped to do a lot of patching just with its own relocation symbol information. And I started looking at, you know, say LD Linux so it's already a JIT micro patching engine. It does simple, simple patches, but it's still a hot patching system. And then we have been LD, LD links, relocatable objects into an executable using really granular Elf relocation metadata. And so just kind of looking and meditating on these things, how can I take what's already done so beautifully and well, and extrapolate on that to make an advanced binary patching system that allows people to patch binaries and see. So I started realizing there's a lot of a lot of power in writing an interpreter and what you can do with it. Started out as writing a modular virus just to be, you know, cool and creative, but I knew it was going to extrapolate into something a little bit more formal. And so you guys, most of you probably familiar with Elf, the PT insert segment holds the path to LD Linux or the dynamic linker that gets replaced with Lib Sheva. And the interpreter generally speaking sets up the finer details of the process image. And the interpreter has instrumentation precedence because it runs before even the real dynamic linker. So another strong aspect of it is, you know, patching memory with P trace is slow because you're in another process and there's a lot of context switching and things that happen. If the patching, you know, engine is in the same address space of the program it's patching, it's much faster. And so, and this is something exploring a different time and more depth, but essentially I started thinking, well, an Elf relocatable objects have really great metadata, enough relocation information to build a process image out of. And so really she was somewhat of a hybrid between LD and LD Linux.so. So it draws wisdom from both linkers. You know, it's flexible, it's modular, like the dynamic linker, LD Linux.so, but it has the nuance of LD because it uses that really granular relocation information that's in those Elf object files. So to kind of further just show how it fits into the existing Elf linking components, you've got LD, it's an Elf linker, got LD Linux.so, that's a linker anteloder because it loads shared libraries and knows how to load executables. And then you have LibSheva, which is an Elf linker loader and a transformer. And we're going to get more into transformation, transforms how they fit on top of relocations a little bit later. But, or maybe right now. So Sheva's innovation and linking concepts. Sheva, just in the research and development of it, you know, I created a number of new techniques that are necessary to kind of bring this all together. One of them I touched on briefly, interpreter chaining, Elf transforms. In fact, I'm not even going to go through the whole list right now. But each one of these is something that's either brand new or being used in a new way. Generally, this is all pretty new concepts that fit really nicely into the existing Elf ABI. We're going to talk deeper about them. Sheva's built on top of LibElf Master. It's a library I wrote in like 2018. It forensically reconstructs broken binaries under the hood. So if a binary has no section headers or symbol tables, it'll reconstruct those based on the EH frame, the dynamic segment, other things and recreate the symbol table internally. So even though Sheva's symbolically driven, it can still work on stripped binaries because of that. So thought might be a question that comes up. So let's take a look at Sheva's Elf linking workflow. So on the very left, we have just two object files, main.o and foo.o being linked into a program, my program. In the middle, we see that that program is now being executed and it has the LD Linux interpreter loading libc.so into memory. That's just the general kind of linking workflow. You move over to very far right and there's a diagram illustrating that Sheva and LD Linux.so are cooperating together in the same address space to transform the program with both the patch and the shared libraries. So the standard Elf dynamic linking workflow essentially looks like this. You've got the kernel is trying to execute a program called test, but first it loads test interpreter, which is LD Linux.so, passes control to it. The dynamic linker loads libc or whatever it's loading and then passes control to bin test, actually passes control to the underscore start function. With linker chaining, where you're linking multiple dynamic linkers into the same address space, you have both libcva and LD Linux.so cooperating together. The kernel loads Sheva, since that's the interpreter, passes control to it. Sheva loads, links and transforms this patch and then it actually user land execs essentially LD Linux.so into memory, maps all the segments into memory, passes control to the real dynamic linker, just like the kernel would. The dynamic linker then loads its shared libraries and then finally passes control to test. That's actually a simple, simple workflow. We'll get deeper later, but I mentioned that elf patches are compiled as just regular relocatable objects. You can use clang or GCC. In the future, I plan to write a compiler wrapper, but essentially, you know, relocatable objects are great for patches. They contain rich symbolic metadata for both relocations, all the symbol names, and I have extended some of it, but generally speaking, the object files are really nice. You have to build them with a large code model. That way, an internal got is used for absolute addresses so that you don't run into a situation where you're further than four gigabytes away from the executable that you need to relink with. So there's that. But I definitely recommend checking out the Sheva module loader function in Sheva underscore module.c. It's definitely where all the most probably interesting code is. Also, you know, after an elf relocatable object is, so an elf relocatable object basically gets loaded into memory. Sheva creates a text segment, data segment, BSS for all the patch information, all the sections are put in their appropriate places, all the relocations for the patches are handled, but then the executable itself needs to be relinked to use the new patch code and data. Well, that's a little difficult because elf executables don't have relocation data that describe how to relocate their own text section. They have a little bit of dynamic linking information, but that's different. They don't have the information that was in the original elf object files because it's not needed anymore. It would be nice, but what Sheva does is it generates a control flow graph and based off that it generates relocations on the fly for the elf executable because there's a lot of relinking and re-encoding of instructions that has to be done if you splice new code in, for instance, all the offsets change, everything changes, and so we're able to handle all that pretty nicely, fluently. So I mentioned briefly Sheva's user land exec functionality and this is just used, kind of like any interpreter with Python, you can call Python directly, same with Sheva, and this is really good for testing a patch. Let's say you want to make no metadata modifications to the binary, just leave the binary completely untouched. You just specify the patch object in the Sheva module path environment variable, and then you run Sheva, and then the program you're trying to execute, and it will load and install the patches all at runtime. If you want the program to be patched every time you run it, without having to execute Sheva, you have to use the Sheva pre-linker. We'll get into that in a minute, but it updates the PT-interp segment with the correct interpreter and also adds a new dynamic segment, a couple other little things. So can everybody see here the requesting program interpreter is Lib Sheva in this program instead of LD Linux? So that's just kind of illustrating for you and what the program looks like after it's been pre-linked. And then if the dynamic segment here, we can see the last three entries towards the bottom here, Sheva needed, and I don't know why you can't see that. There's like something in front of it there, but that's the base name to the patch object Sheva needed. So the needed patch objects, the search right here is the search path to where all the object files are stored. Just like in with the dynamic linker, they're usually stored in Lib. And then it gives the path to the original ELF interpreter so that Sheva knows which path the interpreter is to load and link into memory because it will map the dynamic linker into memory once it's done. So I want to talk about ELF symbol interposition here for a moment. So is anybody familiar with what that term means? ELF symbol interposition? Okay, yeah. So essentially though, think LD preload. It's where you can overwrite one symbol with another symbol because it has the same name based on the precedence of the object that's loaded. So Sheva, one of its really strong features, is that it allows you to rewrite any code and data just by name. You know, as long as there's symbolic data attached to any global data, any global functions, even local functions, although it needs about two days of work to do that. But essentially anything symbolically can be rewritten. It's actually really easy. And so instead of just rewriting functions like with LD preload, you can rewrite anything by name essentially in the executable itself. I want to give it just a little example here. See we're running hello. It says hello world. Can you guys see that okay? It's kind of small. But and then I look at the symbol table and I see there's a string called hello underscore string that lives in the RO data section. And if we, let's say we want to change that program. The program's called hello. And we want to make it so that it prints hello death com 31. So we literally have a very simple patch. We just redefine that constant string by name. We compile it into a L free locatable object with a large code model. And then on this slide we're going to show you how it works. So running hello just runs hello world. But if we set the shiva module path to the patch object and then run shiva on hello, it installs the patch at runtime. Then if you just run it without shiva it just goes back to normal. So this is a great way to test things or just if you only want to do things once or dynamically. Generally speaking though most people want to patch the program permanently. So what you do is you use the shiva prelinker. It's called shiva ld. And it essentially just installs the original interpreter information, the patch metadata such as the location of the patch into the new data segment that it creates in the binary. So the executable code and data isn't changed at all. It's just metadata. So that the new binary uses the correct interpreter path and all that. So we can see we run hello directly now that we prelinked it and it's printing hello defcon 31. So just a simple patch and see. So transformations, I mentioned these earlier. So this is a transformations begin where relocations leave off. I think the dynamic linker is just brilliant. It's a brilliant hot patching mechanism. We can learn a lot from it. Why not take it and utilize it for micro patching binaries. Something of that nature, the same concept, extrapolating on it. So if you know elf relocations are the metadata that describes simple patching operations, then elf transformations would be the metadata that describes complex patching operations such as function splicing, things of that nature. So, you know, function splicing is the ability to splice C code into any function at any given point within the function. Fully relocatable code, fully symbolically rich access to all the shared library symbols functions. And this is this is very complicated. There's a lot of relinking. Many, many magical things have to happen under the hood. But the end result is that we have these transform macros that developers can use to splice code in and out of a function. So this is just a kind of a crude example here, but essentially we have on the left a program that you stir copy. And it's a function called copy string. And let's say we want to modify that function so that it uses stern copy, you know, make sure the string buffer is null terminated. So on the left, you can see the code that's being removed from seven BC down to seven C eight, which will make our stopping address seven CC, by the way. But we want to splice this code, which is larger into this little area there. We want to make it look like this on the right. So how would we do that? So this is actually a transformation patch right here, by giving an example. So up here we have this macro. Shiva T splice function copy string. And remember I gave you the offset seven BC to seven CC. Now these three lines of code are pretty simple. The first line, because the argument stored in the X zero register, because it's ARM, we create a source pointer variable, because it's the argument of the function copy string. And then the destination buffer was at base pointer plus 32. So Shiva gives you macros to access live variables and registers as needed. And then it just does stern copy, source, bobbin. This actually compiles into an object file that looks like this. And I unfortunately don't have all the time I'd like to go on that tangent, but generally speaking, in the tech section here, we have this function. Shiva splice fn name copy string. That tells Shiva, okay, this function right here is actually code that's going to be spliced into a function called copy string. By the way, it won't copy the procedure prologue and epilogue. That's not splice code, but ARM doesn't respect the naked attribute, apparently. So overflow crashes. Okay, so this is a program called overflow. It's the one that I showed you. It's vulnerable. It's got stir copy. We can see that when we pass it four As, it works. When we pass it like over 16 As, it crashes. So we pre-link our patch. This one I showed you right here. We compile into a relocatable object. Pre-link it to the vulnerable program overflow. And then we run overflow and we can see that it works. It's not crashing anymore. That's because it's using stern copy and properly no terminating the string. But just showing how, that's a very simple example. You can splice into any function. That's just to make it palatable in a talk. So spliceable code has some interesting characteristics. I kind of covered some of them. It's fully relocatable, a very rich symbolic access with natural C development. There's no limit or size to the amount of code you can splice into an existing function. And then of course there's macros for gaining access to the live variables and registers on the stack and whatnot. So confluent linking technology. So this is a terminology I've kind of coined, which just means two dynamic linkers working together coherently within one process image to build, transform, and relink the program at runtime. And there are a lot of cases. So there's a couple things here. Cross relocations. This is actually where one dynamic linker relies on another dynamic linker to solve its own relocation. And so an example of this is, let's say you write a patch that has a new BSS variable. It's overwriting another BSS variable in the original program. This is the new version of the variable that should be used. Maybe you had to extend a buffer size or something. Those BSS variables are often accessed indirectly through the got. There's a relative relocation, at least in Pi executables, that fixes up the got to the correct BSS address. So when Shiva, when somebody has a patch with the new BSS variable, for instance, they will, sorry, I'm looking at the timer, they will, Shiva will instruct the other dynamic linker to essentially patch it by modifying the relocation metadata in memory. So you can basically tell the dynamic linker to do whatever you want. You give it a script. The script is the elf sections and the values in the dynamic segment that are read by the dynamic linker. We also have delayed relocations, which we, therefore, we have the Shiva post linker, which actually handles some relocations after ldelinux.so. So Shiva will load, link the patch, pass control to the dynamic linker, and then when the dynamic linker is done, oftentimes it passes control back to a function called Shiva post linker. We actually update the AT entry value in the auxiliary vector, which normally points to the start function of the program, so that it jumps back to the Shiva post linker. The Shiva post linker then finishes handling any delayed relocations and then passes control forward. Shiva was just made open source today. I am excited, grateful to be able to share it with everybody. Please, you know, and there's a user manual, there's quite a bit of documentation, but let's see what time is it here. So let me go into this demo real quick for you guys, okay? I want to... All right, so I want to illustrate an example of symbol interposition and how it can be used to rewrite global code and data on the fly with Shiva in a way that's natural for C developers. So let's take a look at this simple program, test food, and for the sake of illustrating the scenario, I'm going to show you the original source code. So we can see that main simply calls foo and then prints the return value foo, prints I am the original foo function and then it prints the value of lucky number. Lucky number is an initialized global variable so it would live in the data section. So let's say we wanted to rewrite this function and also modify this variable. In fact, we actually want to redeclare this variable. Let's take a look over here on the right side of the screen and this is the actual patch code itself. So as you can see, we've redeclared lucky number as an uninitialized global variable. In Shiva we call this redefinition or redecleration of storage type or storage type redecleration. And then down here we have rewritten foo and this is showing how we can drive our patching through symbolic references. So these symbols exist within the target binary and so we're able to rewrite them using symbol interposition. Now, right here we set the value of lucky number. It's now initialized to 31337. We print I am the new function foo. We print the value of lucky number and then right here we're demonstrating how Shiva patches are able to resolve shared library functions that don't already have a plt entry in the executable that we're patching. And so right here we're calling system to cat the Shiva .ansi file and then we return dead beef. So we have rewritten foo and we have redeclared lucky number as an uninitialized variable. So let's say we want to take this patch and we want to compile it so we would sorry, we would build it just like a relocatable object with a large code model which we have to use no pick and then we have a relocatable object now. You can see the relocations and symbol table. If we want to install this patch there's two ways to do it. So firstly in many cases we just want to try the patch out or just test it once without making any modification at all to the target binary. And so test foo without a patch and now test foo with a patch. We specify the Shiva module path environment variable, export it and then we simply invoke Shiva directly with the patch version. So it has been, the executable has been relinked in memory to use the code and data specified in our patch. Prince I am the new function foo. It then prints 31337 is the lucky number. It prints the Shiva ANSI banner and then prints the return value of dead beef. Now if we wanted to install this patch permanently we would have to use the Shiva pre-linker which installs some metadata such as the path to Shiva into the interp segment and it updates the dynamic segment of the executable and adds a few new entries. So let's let's take a look at that. Let me clear the screen. Shiva LD works like this and so give an example. Dash E is the executable which is test foo. The patch base name is foo patch dot o. The interpreter path is lib Shiva and the search path is opt Shiva modules and then we'll rename it the same name. So if we were to look at the program segments of test foo we can see that lib Shiva is now the interpreter. We also see there's an extra load segment there and that's to make room for the new dynamic segment. So let's take a look at the dynamic segment how it's been modified. So the dynamic segment is actually the same except it has three new entries at the bottom here which a reed elf hasn't been modified to print what these are but this is the addresses to the patch base name, the address to the patch search path, and then the address to the path of the original interpreter which is ldlinux.so and we also have to move the patch or copy the patch into the opt Shiva modules directory because that's the search path that we specified. So in any case now when we run test foo it's patched every single time because of that metadata that's been installed. The only difference between test foo now and before is that the dynamic segment's been updated and the PT interrupt segment has been updated. And so another neat little feature is if you call Shiva directly again with the dash u flag on test foo we'll actually run test foo and it won't run it without installing all the patches. So that's kind of a neat feature. And next we're going to look at transformations with function splicing. Thank you there's more! Okay so i'm going to try to demonstrate elf transformations as concisely as i can in this example with a program called test prog. So let's take a quick look at the original source code. So we have this function foo here. foo is called down here in main and foo says if this first argument none is equal to seven then go to done. Otherwise copy banner which is this const pointer to the string elf master over into global buff. Global buff is a bss buffer and then it prints the value of this argument string. And so what we want to do here is actually overwrite this function called to printf with some code that first checks to see if str is equal to null. And if it's not then it will print it. And then also we want our code our patch code to print the value of global buff. And so let's take a look here. There's a number of things happening in this patch. So we're actually going to start at the bottom. So firstly over here on the left in the original source we have bar and in our patch code we rewrite bar. As we can see adds the value of two global variables that were added in this patch this dataVal. It adds the variables together and then prints the sum. And then up here so bar is being completely rewritten with symbol interposition. And then moving up here we have the actual splice code the splice patch. This is how transformations work when developing shiva patches that need to splice code into an existing function. And so this macro right here is used. So we are splicing into the function foo. The address to start patching at is 818 and the stop address is 828. And so coming down into the actual splice code let's start right here. We have if str is not equal to null then print the string. And if you notice we're using fprintf instead of printf which was in the original program. And this is again just illustrating strong global symbol resolution. And then after that we use fprintf to print the value of global buff which illustrates our patch ability to use the x-turn keyword. So you were using the x-turn keyword to get a hold of global buff which is a global variable from the program that we're patching. And so after that we call bar. And this is illustrating how our patch code will link to the new function bar instead of the original function bar. And when main calls bar it will also link to our new function bar of course. Anyhow so back up to this transformation macro. We want to patch at 818. Let's take a good look at why. So we'll look at the program assembly down here at function foo. We're going to be patching from here to here. Actually to right here. So our start address is 818. And the last address that we patch is 824 which makes our stop address 828. And 828 and all of the code after it will be shifted forward as needed based on the size of the code being spliced in. And in our case we're splicing a larger amount of code in. Let's just build our patch real quickly. And now we have a relocatable object called patch.o. These are the relocations for it. And if we look at use object dump. You can see this is the splice code. This whole function right here. And you can see it uses a special symbol name called shiva splice fn name. And then the function that's being spliced as foo. This direct shiva to use the function splice and capabilities. And so shiva will splice all of this code in. The procedure prologue and epilogue won't be included. All of this code will be relocated and transformed essentially. It will be inserted and spliced into the function foo. Again into this location right here. So we're actually adding quite a bit of code. And so this will rewrite the entire function foo. It will actually be rewritten for scratch in a different area in memory. And the reason that in the source code I included this ifnum is equal to 7 go to done is to illustrate how it will have to be the assembly code for that will have to be relinked in the binary or in memory. Once our patch code is inserted here because the patch code is much larger and so for this to jump down to done the offsets will change. So this also patching this program also illustrates shiva's ability to relink the executable as needed when the patch code extends the size of the function. And this works by shiva generating on-the-fly relocations for the executable by looking at a control flow graph. And so anyhow let's just try to install this patch and and see how it works. So again testprog looks like this when we run it. Now let's install the patch dynamically. We'll just run shiva directly. The patch is patch.o and the shiva will run shiva directly and execute testprog. And now we see it's working as expected. It only prints the argument we pass it when we actually pass it an argument. See? And if we don't pass it an argument does it. And if we put seven arguments it jumps right down to done and doesn't print, doesn't do any of the other stuff that it was doing. So it's actually working exactly how we modified the program to behave. Now again if we run testprog without shiva it still does the same old behavior. If we want to link the program permanently then we use the shiva pre-linker as demonstrated before. The path is off shiva modules. The output is testprog. We need to copy the patch into off shiva modules just the same way we copy a shared object into the live directory. So now when we run shiva directly or I mean when we run the program directly it works every time it's patched. And again the program's metadata has been modified. We can see libshiva is the interpreter etc. So that is Function Splicing. Yes. Thank you. What happened to my slides there? So just I got a couple minutes left here. Let me pop the slides back up. And I'm not really familiar with Adobe. But whatever the case, that's still... Well there really wasn't. There's one last slide here. Give me just a moment. What's that? Yes. Thank you. Look at me. Here I am. So I guess you can specify the slide too. I think it's like slide 51 that I'm looking for. If you close your eyes I don't want to cause any seizures. Thank you. So first I just want to say thank you to my son Jayden for helping me with the video editing. It's not my strong suit for the demo. Thank you Jayden. Appreciate that. Act Gamer Tries on YouTube. And I want to say thank you to my wife Teresa O'Neill for being such a powerhouse behind me. Thank you honey. And my mother. My mother bought me every book by what's his name? Richard Stevenson by the time I was about 16. I had them all. Unix Network Programming. She was on it to help me get educated on what I wanted to learn. So thanks mom. Love you. And thanks to my son Mick for being here. He just turned 18. So super grateful to have my family with me and super grateful to be able to share this with you guys. I have open sourced it today. There's I'm sure email me if you have any problems. There's the Sheva user manual. It's still a work in progress, but it gets deeper. There's also some design specifications that are in the Sheva repository. They're a little behind date, but if you want to learn more about it, go to the website arcanaresearch.io, Sheva. And feel free to reach out to me for any questions about it. And thank you. Grateful for everybody being present. Is there any questions for 30 seconds? You got three seconds.