 All right, good morning, everyone. Thanks for being here. My name is Christopher Domus. I work for this R and D company called the Battelle Memorial Institute. It's a pretty neat place to work. Gives me a chance to look at a lot of the fringe areas of cybersecurity, which keeps things entertaining. But important disclaimer before I begin, everything I'm going to show is just my own work and my own opinions. Second important disclaimer, everything I'm going to show serves absolutely no purpose whatsoever. So if you're really interested in a practical talk, this is probably not the right place to be, but I think it's still going to be really entertaining and hopefully see some interesting stuff. So what I really want to talk to you about today is reverse engineering because I do a lot of reverse engineering. I take software apart and figure out basically how it works. But for whatever reason, I also spend a tremendous amount of time trying to think about how I can make my life more difficult. In other words, how can I make it harder to take software apart and figure out how it works? So there's a couple of basic ways people normally approach that problem of making things more difficult to reverse engineer to take apart. Encryption is a pretty common one to make things harder to understand. Obfuscation of code is another technique people use to make things harder to understand. And entity debugging tricks are yet another tool that people commonly use for anti-reverse engineering, again, to make things harder to understand. There's kind of a theme in all the approaches people normally take for anti-reverse engineering. You're just trying to make things more difficult to decipher. So I was tinkering around with that over the last few months. And I kind of came up with this neat way that incorporates all of those things at once as an anti-reverse engineering technique. And the idea behind this whole thing is that for the most part in reverse engineering, we're going to look at the individual pieces inside of a program in order to try to understand what that program is doing. So using a tool like Obstump here, we can look at the individual instructions inside of some unknown file and we can figure out exactly how that file is going to work. We can take it apart and figure out what it's doing. So if I ran Obstump on some file, I might get something like this. So an experienced reverse engineer could tell exactly what this was doing in a couple of seconds. Even somebody with no reverse engineering background can actually pick this apart and tell what it's doing with almost no time at all. So starting out, just looking mostly at the mnemonics that are going on here, it's moving zero into memory. That's going to be initializing a local variable. It's pushing something out of the stack as an argument and then it's calling a function to print that argument out. It removes that thing from the stack and it adds one to its local variable. It then compares the local variable to 100 and if that is less than or equal to 100, it jumps back to the beginning here. So basically it's just going to sit in a loop 100 times printing something out. And no time at all, really just by looking at the instructions being used, we can understand exactly what this program was trying to do. But a few months ago, I was reading this paper that I found really, really interesting. It was just called Move is Turning Complete by a guy named Steven Dolan. So really, really simple concept. If you're not familiar with the move instruction, it's a common instruction, basically the simplest instruction in all of x86. It just moves data from one location to another. Nothing more involved in it. So what about that Turing Complete part? Well, that means that any code that we write in any language could really just be written as a set of these unconditional data transfers instead and absolutely nothing else. And when you think about everything you do in a program that's actually kind of mind boggling, it's hard to believe when you think that we're doing arithmetic and comparisons and jumps and function calls and exception handling in our program. Theoretically, all we need to implement all of that stuff is just a bunch of move instructions. And as I thought about that more and more, I thought, well, that would be really, really hard to reverse engineer, wouldn't it? Because we would go from something like this where we've got all these instructions that perfectly tell us what's going on inside of the program where we can instantly understand what this program is doing to just a whole bunch of unconditional data transfers instead. So all of a sudden all the cues we use for reverse engineering have just been removed from the program. We've got nothing to go off of anymore. Every instruction looks exactly like every other instruction. It is really, really hard to reverse engineer this kind of thing. So I took that idea and I've been running with it over the last few months. And at the beginning of DefCon on Thursday, I released a move only C compiler that will take C source code and translate it into only move instructions. So this is pretty fun. And as far as I know, this is the first single instruction C compiler ever. Mostly because I don't think anybody's ever wanted to create such a thing before. But it turns out to be kind of neat. So I called this thing the Mophiskator because it turns programs into moves as an obfuscation technique. And we can really do anything with it. So for example, I've got this really simple little C program that prints out prime numbers. So not much involved there. And I could compile this with a traditional compiler like GCC and look at the instructions it gives me. And that's great. But if I look at these instructions, it takes almost no time at all for an experienced reverse engineer to pick this thing apart and understand exactly how it's working. But on the other hand, if we use the Mophiskator, the Moph CC compiler, I do the exact same thing, all of a sudden we've got nothing but thousands and thousands of unconditional move instructions implementing this thing. But the cool part is if we run this, it just calculated 10,000 prime numbers using nothing but unconditional data transfers. But that is a nightmare to try to reverse engineer that kind of thing. But it's not limited to simple little examples like this. If you go onto that GitHub page, it'll include this little check script. So what the check script is going to do is it's going to automatically download an open source AES implementation in C. It's going to run that through the Moof compiler. As soon as it's finished compiling the thing, it's going to dump out the move instructions associated with that. And you'll see that with just a couple million move instructions, you can implement AES. So this is not fun to work with as a reverse engineer. But it's really, really neat to think about that just by moving data from one place to another, we can do really, really complex computations. So I sort of meant this as like a thought experiment in anti-reverse engineering, but mostly I just thought it was funny that you could have move instructions doing really, really complicated things. So it finally finished running that and it'll actually run our AES algorithm and encrypt and decrypt some data using only move instructions. But we can make it more complicated. I wrote a little Nibbles game. If we link that, so we can play video games now with only move instructions. We can take it a step further. My, or the move compiler we created actually contains a complete move only floating point emulator. So you can do floating point math with only move instructions. So since I could do that, I decided, well, what's the best demonstration of floating point math I could come up with? I figured I could make a 3D engine, which is a lot of floating point math, like trigonometric functions and matrix transforms. And then I could compile that with the Mophiskator. So we've got a complete little 3D program here, written with only move instructions. We can now do incredibly complicated 3D calculations. I even took this as bad as far as I could possibly conceive. And actually Mophiskated the Mophiskator. So I've got a program written in only move instructions that compiles other programs into only move instructions. So that's a couple million lines. We're not going to sit around waiting for that to finish dumping. So I thought this was a really cool technique. If you actually like reverse engineering, you can check out some crack knees on that GitHub page and see move only reverse engineering for yourself. But after I finished this, I started giving this some serious thought from a reverse engineering perspective. I thought, how would an experienced reverse engineer approach reverse engineering something like this? What would I do if I looked at a program and I opened it up and all I saw were hundreds of thousands of unconditional data transfers? Realistically, I'd go find something else to do. I reverse engineer because I think it's fun and this does not look like fun to me. But I had a big realization at that moment. From an anti-reverse engineering perspective, code doesn't really have to be hard to reverse engineer. All we really need to succeed in anti-reverse engineering is none of the things we've traditionally been using. We don't need encryption. We don't need obfuscation or anti-debugging. All we really need at the end of the day is we need to make the reverse engineer give up. That's not necessarily the same as making code hard to reverse. So I started thinking, how else could we make a reverser quit? If we don't want them to reverse engineer our code, how could we stop them from looking at it in the first place? And I thought the obvious solution was psychological warfare. We could demoralize the reverse engineer and try to break down their spirit until they had no more will to continue reverse engineering our code. So I started thinking how could we actually accomplish that, though? It seemed clear that if we wanted to somehow demoralize a reverse engineer, we needed some way to influence them. We needed a way to influence the reverse engineer through our code. All they're going to get is some compiled binary. And I need some way to have that binary then influence the person looking at it to try to get them to stop looking at it. So it seemed clear to me if I wanted my binary to influence a reverse engineer, I needed some way to send them messages through that compiled code. So there's some easy ways we could try to send a reverse engineer messages. We could just embed a string in our program, like stop looking at my code. The reverse engineer when they're dissecting our program will probably eventually see that string. But that's not a very good technique. I'm a reverse engineer. If I saw somebody put a string in their binary saying stop reverse engineering me, I'd probably laugh at that. That's just, that's silly. That's not going to be effective. So string is not a really good solution. Then I thought entropy. A lot of modern programs are starting to look at entropy distributions as a reliable way of some types of reverse engineering. So like if you download the latest version of Hopper, the reverse engineering tool for the Mac, they actually have entropy visualization through Hilbert curves inside of Hopper. So I thought, well maybe if I ran my message to an inverse Hilbert transform and adjusted the entropy inside of my program, I could then send the reverse engineer messages through the entropy distribution of my program. But so it works. You can do this. But again, not the most effective technique. Somebody's going to see this and then just move on to reverse engineering your code. So still not going to really accomplish what we want. All these are horrible solutions for sending a message to a reverse engineer. At the end of the day, no one's going to see the message. If they do, they just won't care. They're going to move on, keep reverse engineering. So we need something better if we really want to be able to send a message to reverse engineers. So I started thinking about the tools that I used for reverse engineering. So if you're not familiar, this is IDA-PRO. This is probably the de facto standard in static reverse engineering. Any professional reverse engineer is going to be using IDA-PRO to dissect your code. So I really wanted to focus on IDA as a means for sending messages to reverse engineers. And IDA can do some basic things for us. Like it can show us the code inside of a program just like we were doing with Obstump before. But IDA has a more powerful capability. And that's control flow graphs. So the idea behind control flow graphs is something like this. We've got these basic blocks that do simple things. And then at the end of a basic block, the program makes some kind of determination. And it's going to go down one path if it decided that thing was true or a different path if it decided that thing was false. So we've got a whole bunch of these basic blocks that are all connected by decisions inside of the program. The nice thing about these control flow graphs is in just a couple of seconds I can tell at a high level exactly what this program is going to be doing. So for example, this branch here is going to be an if statement. This arrow going back here, that's a loop happening inside of the code. So at the end of the day, most reverse engineering is going to be done at this level. Looking at control flow graphs to quickly get an idea of what's inside of assembly. So almost every major, at least static reverse engineering tool is going to have control flow graph support. And anybody doing static reverse engineering is going to spend a lot of time looking at this. So the hopper reverse engineering tool for Mac has control flow graphs. Bin NABY, control flow graphs. Rodare has control flow graphs. This is the thing to use for reverse engineering. So for this presentation we're going to look at IDA a little bit, but the algorithm itself will work on pretty much any of these tools that you look at. So the idea behind this was sort of spawned from a lot of late nights of reverse engineering. So when it's 3 a.m. and you're looking at assembly code and control flow graphs and you haven't slept for 30 hours because you're just staring at this thing, you're not entirely with it at some point. So if you stare at these control flow graphs long enough, what I found is eventually they start to look like things. So this is a very, very simple control flow graph in IDA, but a lot of professional reverse engineers are dealing with very, very complicated control flow graphs in IDA. And when you're dozing off at 3 a.m. once in a while, you'll start to see things inside of these images. So I felt like this was a Tyrannosaurus Rex at 4 in the morning, but that gave me an idea. Maybe we could send the reverse engineer a message through control flow graphs because that's something they can't look away from. That's exactly what they're looking at in our program. So if we could send them a message through the control flow graph, they've got to stare at our message, which is exactly what we want. So maybe we could like draw pictures with the control flow graph. Maybe we could send them texts through the control flow graphs of our program. But in order to do that, we need to understand exactly how our reverse engineering tools are rendering these control flow graphs. In other words, we kind of need to be able to reverse engineer IDA to figure out how it works. So it's a little bit of a daunting prospect to reverse engineering tool, but it actually turns out to be fairly straightforward if you just tinker with it for long enough. So my first idea for how we could draw pictures or send messages through control flow graphs was pretty simple. I stared at enough assembly and control flow graphs to know exactly how to draw a horizontal line. If you have a switch statement and like see, it will draw a horizontal line when you're looking at a control flow graph. What I call orphan jumps will also do that. So let's say you've got a whole bunch of jumps that all jump to exactly one location. It's not really clear how the program got to this jump here because the instruction right before it didn't go to this jump. So we've got all these jumps that didn't seem to come from anywhere. When you have that situation, it turns into basically a horizontal line in the control flow graph. So I can draw horizontal lines using that technique. I can draw vertical lines in a much easier way. Basically any non-branching code in a control flow graph will create a vertical line. So a whole bunch of knobs that don't do anything creates a nice solid vertical line when looked at in a control flow graph. So I thought, well, I've got horizontal lines. I've got vertical lines. I can make an etch a sketch in IDA. So that seemed easy enough. All I wanted to do was start out by drawing a square. So here's how I thought you would draw a square with these techniques. All we're going to do at the top is have a bunch of jumps that all jump to one location to draw a horizontal line. Then we need that horizontal line to connect to both sides of the square. So on the left we're going to have a jump to the left vertical line. And on the right we're going to have a jump to the right vertical line. So left slide is just going to be a whole bunch of knobs that don't do anything to draw that vertical line and then we're going to tie it to the bottom line with a jump. And on the right side a whole bunch of nots that don't do anything to create a vertical line. We're going to tie it to the bottom horizontal line. Same thing for the bottom. We're just going to draw a horizontal line. Easy enough. But when we drop this into IDA to look at the control flow graph, we're not quite to a square just yet. We need to make some modifications to this. But this tells us a little bit about how IDA is trying to lay out these control flow graphs. So if we look at this piece here, this tells us a little bit that IDA is actually trying to combine or trying to line up a bunch of our nodes. Trying to line the blocks in a given row. So we need IDA to not do that if I want that horizontal line to move back to the bottom of the square. So instead of using nots for my vertical lines I decided we could use this jump plus two. All that is is a jump to the instruction immediately following it. What that's going to do is it's going to break those vertical lines up into a whole bunch of little nodes so that when we try to draw this again, IDA aligns our bottom line with the last set of little nodes in our vertical line. So I at least got the bottom line moved to the bottom here. We're getting a little bit closer to actually being able to etch a sketch inside of IDA. But obviously there's still an issue. I've still got my vertical lines right next to each other. I wanted those to be on opposite ends of the square. So we kind of see that IDA is trying to keep rows and columns together. It's squeezing all of our control flow graph into small and area as possible. And it does that in order to sort of minimize the branching distance inside of this thing. So I spent a couple hours tinkering with this and really could never find a way to get those horizontal or those vertical lines to separate from each other. So that's sort of the death of my first idea for how we could draw through control flow graphs. But we learned a lot along the way. We learned about how rows and columns are arranged in IDA. Namely that we have control over how the rows are arranged. But IDA is going to have control over all of those columns. So we need some way to fight back against IDA. If IDA is trying to rearrange our stuff, I need to have some way to stop IDA from changing my stuff around. So my idea was to force IDA to keep all these nodes in place. I could sort of tie the nodes together as tightly as possible to prevent IDA from trying to rearrange them. So if we look at what a basic node in assembly looks like, it's pretty much always like this. It's a bunch of assembly instructions that do something and then at the end it branches to either one location or another. So I thought what if we had a whole bunch of these nodes and we tied them together like this, then IDA couldn't really move any one node because it's going to be trying to pull all the other nodes with it. So this will force IDA to try to keep everything in place for us. So the assembly to accomplish that looks something like this. All we have is a conditional jump at this instruction down to either this place or it's going to fall through to the node below. This one will jump over here or it will fall through to the node below. So we've got a whole bunch of instructions that are all tightly tied together in this sort of matrix formation. And we look at what that looks like in a control flow graph view. This is what we end up with. It's actually not that bad. We have defined structure that was somewhat close to what we expected to accomplish. So we can touch this up a little bit. First we've got this giant block here that seems to be raising the nodes around it. So we can cut that giant block in half by adding a jump into the middle of that. So we need some way to create a whole bunch of these. I don't want to create a whole bunch of these by hand. NASM fortunately has some really really powerful preprocessor macros. So this is just all the code we need to create NASM macros to generate one of these matrix or one of these layouts for us. So that lets us create a whole bunch of these nodes very, very quickly so that we can begin looking at more complex patterns through the control flow graph. But I've got kind of an issue here, right? I want to draw something with this but I've got this like lopsided rhombus. It's going to be hard to draw with a lopsided rhombus. What I really wanted was like this perfect grid of assembly nodes that I could work with. So we just need to change a little bit about the way we're building this graph. What we're ultimately going to be after is a way to draw with these nodes by turning pixels on and off by removing or adding nodes in exactly the right location. So I thought something like this, if I wanted to have this pixel off I'm just going to remove this node and I could draw that way. So first we're going to try to get this into a non rhombus shape. We're just going to rearrange our control flow graph by tying the nodes together a little bit differently. We take it with the assembly a little bit. It's a little bit trickier to write things this way and when we drop that into AIDA this is what we end up with. It looks like a garbled mess that doesn't at all accomplish what we want but if we look really carefully there's four nodes there that are perfectly arranged in a grid pattern. So I can work with that. If we've got four nodes in a grid pattern we can get more nodes in a grid pattern. So back to NASM's preprocessor. We can use a preprocessor to generate a whole bunch of these and this is what we end up with. We're getting almost to perfectly well defined structure that we actually have some decent control over and maybe we could start using this then to send some messages to the reverse engineer. We've got a few things to touch up here. First we've got this weird line on top. Again we're going to cut that big node in half by adding an unconditional jump. In the middle of that we've got some nodes escaping from us on the right. I decided I could push those back into the rest of the image by having a bunch of orphan jumps to each of the nodes on the right. Now we've got another issue. We've got a rectangle here. It's not a square. So all we really need to do to make this into a square is add a whole bunch of junk instructions and each individual node and we'll make this thing a little bit taller. Once again though we've got some nodes trying to escape from us. This was a little bit difficult to figure out what was going on here. It turns out that NASM, the assembler we're using to do this, uses two different forms of jump instructions depending on how far you have to jump. These nodes down here had to jump a little bit further than the rest of these nodes up here which essentially made them wider than the other nodes inside of IDA. All we have to do is turn off optimizations in NASM in order to use the same jump instruction for every node and we finally have a perfect grid that we can actually start trying to draw on. So we're finally ready to implement our idea. Maybe we can start drawing on this by turning these nodes on and off by simply removing a node. So I tried to remove a single node from this and the entire thing breaks. IDA tries to squeeze all the nodes around that thing together so we can't really get a nice image by trying to delete nodes from this graph. So that was the death of a very long idea too. But maybe we can resurrect it. I didn't take you this far for nothing. We can still, well we can't remove a node from this but maybe we could do something similar. Maybe we could leave all the nodes in place and then fill a node with code if we want it to be on or leave it empty if we wanted it to be off. So something like this. The nodes that I actually want to look like they're on are going to have a jump instruction. The nodes that are off aren't deleted. They still exist and they're still tied to the nodes around them with a jump instruction but they don't have any dummy code inside of them in order to fill up that node. So now when we try that we almost get the effect we want. We can see this looks like a pixel that's been turned off inside of our control flow graph. So with that we can extend the idea and begin actually drawing some things inside of the control flow graph. There are a few things I wanted to touch up here. I decided to get rid of this giant node at top. That's how she caused because this is the first function in the program and AIDA is adding a whole bunch of additional information to that node so we just make this thing not the first function we get rid of that. We've got these funny little orphan jumps on top. We'll just add some dummy code to get rid of those. I really want to enhance the contrast in this if I go back a slide and I want to enhance the contrast for the image that we're trying to draw. Well, the idea is that an empty pixel here still used two lines that had that jump instruction in a label. All we really want to do to enhance contrast is reduce the impact of those two lines and you can reduce the impact of those two lines by increasing the height of the overall node. That way those two lines won't matter that much in comparison to everything else. But in order to increase the height of the node we need is a really, really long assembly instruction in order to make that node take up as wide a space as possible. So there might be longer assembly instructions in x86 but this was the longest one I could think of off the top of my head. That's vector fused, multiply, alternating atoms of track from packed single precision floating point data using the XMM registers with a CS override in a very complex addressing mode. So this is a weird architecture that lets you do insanely long assembly. This is really convenient because it let me get the enhanced contrast that I was after. Making each node really, really wide. So we've introduced new issues. We've still got nodes trying to escape again. So every time these nodes try to escape we've got to push them back in place and the reason these nodes are trying to escape is because we made this node really, really wide. But now the jumps that I was using to push all those nodes over to the left, those nodes are really, really small compared to these really, really wide instructions to those jumps that push everything in place. So after we do that we've got this nice perfect grid with a circle drawn in the middle. So we're getting, we're getting there, there's a few more things to tweak along the way. There's an issue where if we had all the pixels in our row turned off the entire image would collapse on itself. So we keep the column on the far left always on to prevent the image from collapsing. I didn't like the idea of having knobs filling up these, these nodes. Knops are very clearly not code. So I added a junk code generator that would add some dummy instructions that don't really do anything but they also don't fault the program so they can actually run. Finally I didn't want to have to draw this thing by hand every time. I had to draw that stupid circle by hand. So I created a bitmap to NASM preprocessor assigned directive converter so that we could actually take bitmap images and convert those into NASM constants. That lets us take a bitmap image converted into these pixel values that we can feed to NASM in order to generate the code for us. So finally we can take a bitmap image like a smiley face, run it through this entire process and create a control flow graph for the smiley face. So we're getting a little bit further. There's still some things I didn't really like about this. I'm a little anal retentive. I didn't like the fact that there's a blue line on the bottom but not a blue line on the top. So I fixed that by opening the whole thing with a switch statement that was going to tie all the top nodes together. Once I did that I figured out that all the work I really went through to tie all these things carefully together as necessary. As long as you tie the top and bottom together like that, you don't need to tie the individual nodes together quite so tightly. They'll stay in place as long as the top and bottom are in place. In other words, whereas before we had this node tied to this node and this node, we no longer need that. We can just have this node fall directly into the node right below it. So that forms what I call the Recite Toolchain, Reverse Engineering Psychological Warfare Toolchain. I'll show exactly how we can use this for some things coming up. But what this does is it gives us a way to generate assembly instructions such that they form images in their control flow graphs. So collectively, if I go into my Recite Source, what I've got here is a bitmap image that I want to render. And it's really, really small but it's just a skull. And that's what I want to turn into assembly instructions to manipulate the control flow graph of my program. So what we're going to do is run Make to turn that image into some assembly code. And all it's going to do is turn that image into a bunch of pre-processor directives. So now that we've got that as pre-processor directives, we're going to go ahead and make an executable whose control flow graph will mimic that image. So we run Make, run it through this whole thing, and it will generate some functioning executables. You can make these executables do whatever you want for these purposes. I decided to make them render Pusheen the cat. So they actually run. They're not fake executables, they run. But if a reverse engineer wanted to approach this and figure out exactly what this program did, they're going to have to go over to their trusty tool IDA and pull in this executable and examine the control flow graph. So when they do that, they then see the image that we just created. I know he's using a lot of lyric. There you go. What an optimum time for a tiny break in the action. How is he doing? I think you all know about our little tradition, new speaker. Welcome to all the new attendees at DEF CON this year. Here's to you. Good job. All right, thanks, guys. Give me a second to get back on track now. So I was trying to think of where else we could take this thing. I don't know what to do with these images. We're trying to let the reverse engineer know what we think of their work. So we can let them know that maybe our code doesn't even do anything useful. You know, maybe this whole time we're just trolling them. Or we can let them know what we really think about then poking around in the code that we work really, really hard to create. But ultimately the goal wasn't just to send them amusing pictures. It was psychological warfare. We wanted them to stop reverse engineering our code. But I think this opens up a neat opportunity. Namely as a reverse engineer I have to sit and look at those control flow graphs. The reversers force to sit and stare at whatever message you embed and use this to your advantage. Crush their soul. Basically make them abandon hope and not want to reverse engineer your code anymore. So what else could we put in here in order to accomplish that task? Well, we could let them know that the entire situation is futile, right? Just remind them constantly. This isn't going to turn out in your favor. You could remind them that if we're good enough to send them messages in our control flow graphs, they're never going to successfully reverse engineer our program. So they might as well just give up now. Or we could just really go all out and I think this one's over the top. And just remind them that they're really no good at life in general and should quit altogether. I was having to realize that we're not limited to black and white images here. The way we have it, we sort of got these nodes either on or off. But we could sort of make them gray or not gray by adding more or fewer instructions to this thing. So I took that opportunity to add grayscale support to this so that we could actually render grayscale images. And of course that opened up a really important opportunity in cybersecurity history. I decided to take the first, as far as I know, assembly selfie. From back when I had hair, so I look a little bit different. But it is completely functioning assembly code. So what I really like about the group I work in is I can take something stupid that I made like this and show it to everyone and they'll have 100 good ideas for how to do it. So what I really like about the group I work in is that when you drop it into IDA, you'll find out where your malware came from. It was North Korea. Another co-worker recommended the ultimate CTF problem, which you could spend hundreds of hours reversing. But all you really needed to do was zoom out and figure out that they were just sending you on your phone. So some of the projectors work here. That's a real QR code. It'll really take you somewhere, but you can check that out later on the slides if you have a chance. But that's one type of CTF problem. But I felt like if this were the DEF CON CTF, they probably wouldn't embed a QR code inside of this thing. No DEF CON CTF seems to be complete without GOATC. So for DEF CON CTF, I felt like it would be GOATC, but I wasn't really going to show you guys GOATC, so you're welcome. But my favorite of all, a friend of mine proposed what could be the creepiest malware of all time. What if we had a piece of malware that would actually scan your hard disk, retrieve your personal images, and then rewrite its code on the images it was collecting. So this took quite a bit of modifications. It's fairly different from what I originally wrote, but I threw together this little C program that would do exactly that. So if we go ahead and run this little piece of malware, it doesn't seem to do anything. It just sits there. Nothing important. But I do have some vacation pictures on here. These are stock photos. Those are not my feet, and this is what we're doing. I would toss this into AIDA. I get rid of that folder I accidentally created. So first in AIDA, after AIDA processes it, it's really not anything interesting. There's nothing in the control flow graph at first. So I'd analyze this a little bit as a reverse engineer. I wouldn't see anything interesting. At some point I'm going to have to do dynamic analysis. I'm going to have to actually run this thing and see what it's doing. I'm going to see what it's doing. So the program begins to run, but the first thing it does is it triggers a software breakpoint. It does that because it wants the reverse engineering tool to stop. It wants you to see what it's actually doing. So I'm going to follow this in my reverse engineering tool and pull out the control flow graph so I can figure out what this malware is doing. We zoom out a little bit here. AIDA doesn't like doing this so much when the program is actually running. This is where my feet. If I keep running this, maybe it's just a fluke. No, the malware is going to stop me again. It's got something new. What's it this time? That's my dog. Why is my dog in the malware? I'm always a little worried to get this demo because I hope it's going to find those two pictures, but I never know what it's really going to go out and collect. But as a reverse engineer, when malware starts rewriting itself on my personal information, that's probably when I'm going to call it quits. So I feel like this would successfully implements what we originally after. Other ways of getting the reverse engineer to stop looking at our code. So there might be other ways to accomplish that. I think it needs to keep your mind open and realize it's not just about making things harder to reverse. But overall this was a really, really fun thing to just tinker with. It was a really fun thing to accomplish this in 328 lines of preprocessor macros. But not too shabby. If you're interested in this, it's on my github at github.com or eax, eax, eax. That is the re-site tool chain is what I call that. I would love to get feedback and ideas on other applications for this. Maybe it's just a fun toy, or maybe there's actually something useful we could do with this. If you're interested in the Motha Skater on github as of Thursday morning if you caught me at Black Hat I released an architectural vulnerability built into the x86 processor itself. Some proof of concept code for that's also on github. But I'd love to discuss this more with anybody who has some interesting ideas for what we could do through control flow graphs. And I might keep tinkering with this over the upcoming week. So if you're interested in tracking progress, you can follow me on Twitter at gmail.com if you want to discuss further. Thanks for your time, everyone. This was a fun project. I really appreciate everyone turning up for it. So if anyone has questions you can talk to me.