So what I'm going to be talking about here is basically some ‑‑ not even really fancy pants thing. It's more of an artistic expression if anything else, if you really want to call it that.   Is it there? I'm totally sending a signal. Maybe I'm not. Hang on. Let's try this. Yeah. Yes, no. Nothing. There we go. All right. Okay. So my name is Frank too. It's not actually Frank squared.  And I've been trying to ‑‑ I tried to socially engineer them to get rid of the account because hey, it's technically a spam account and I can get rid of it.  A lot of people recognize me by my hat. I'm with DC949 and DC310 and I also work for Rapid 7. I can't put that there because there's a lot of F bombs here. My manager did not want me to do that. So I gave this talk at ThoughtCon but I was given only about, I want to say, 15 minutes or so to speak. And this is kind of a complex topic. So it was basically a standard performance that just so happened to feature reverse engineering and all sorts of funny stuff like that. And there were basically two camps.  And then there was this dude on Reddit who saw my slides and he was upset with all the weed references and he was, you know, angered that such a serious topic wasn't really covered so seriously.  So I kind of want to focus on this quote, nothing personal to the dude from Reddit if he just so happens to be in this audience.  But at the same time I kind of feel like people don't really present their information in a very entertaining way even though it is. It's always very cut and dry. Here is EIP, here is ESP, here is how you perform exploit, here is my ode, now clap. And a lot of people, it just seems like, thank you, I appreciate that. And it just seems like to me that this stuff is just, there's so much entertainment at this convention alone. So it just feels like a lot of people should be presenting it in an entertaining fashion and that's what I'm trying to do. So this is basically what you're going to see.  So I hope you'll appreciate it, that's exactly what I'm going to try for here. If you came for a serious talk, I'm very sorry. So if you look at the, this is basically a very scientific analysis of the previous talk that I gave. If you compare the science to the medication quote unquote that I took while performing, not performing the talk but writing it, you'll see that there was a lot more medication involved. But don't worry because there's a little bit more science now. So if you were, well, technically that counted as medication, so I'm not sure. I would probably have to increase the bar a little bit. Anyway, so here's the content. A while back, my friend Merlin right here who is sitting in the front stage wrote this really awesome IRC Python repo bot that basically takes one lines. It was a really awesome exercise in teaching functional programming. It's a whole lot of fun to mess with. You don't even really have to, or you can just add function after function after function. This is actually a combination of all sorts of different functions here.  And it's, it's one of the silliest things you can do. But I mean, look at that.  And it's, it's just beautiful. And for some reason I thought, Hey, what if I applied this to binary obfuscation? I have no idea what, why I came to that conclusion. But it turned out awesome nonetheless. So I'm going to cover a few basics here before continuing. This is the second I need some water. So f of x formulas are actually, you know, very simple in their concept. I mean, you have they work exactly like regular functions.  So you get whatever x was times seven equals your value. You know, in Python, you can make a lambda function, lambda xx times seven. If you want to do Java, I'm sorry. I really don't think you should do that. And, you know, mathematical functions can get a whole lot more complicated than just this.  How does it, how do they work?  And they can get a whole lot more complicated. But this is, it's a very basic concept. As far as assembly is concerned, you have your jump and call instructions. But when you see them in a, in a debugger, specifically, they don't, they look like it's, but it's like jump zero, zero, four, zero, one, zero, zero, at least that's what it looks like in the debugger.  Call is the exact same way, but it pushes a whole bunch of stuff onto your stack. Except for the fact when you have like jump EAX or jump dereference EAX or things like that, that is actually a specific call to an address. And usually you don't, you don't have the ability to determine what's in EAX just specifically from doing disassembly or anything like that. This will come up later. It's, it can be an issue. So you have to be aware of it. So let's talk about jump short for a bit. So jump short. See now you're starting to figure it out. Thank you. So jump short is a special jump instruction in the X86 architecture that allows you to have a single byte offset instead of a four byte offset, which reduces a lot of space. This is going to be significant again later on because of all the manipulation that's going to be happening with the individual instructions. So it's important to keep in mind that, you know, a jump short only has a range of about 256 signed. I can't even remember how big the number is for a four byte number and don't even get me started on 64 bit. There's no such thing as call short and jump short and call short. Who knows? So here's some computer science witchcraft. In the middle of making these slides, I realized that, you know, you can actually define the assembly as null space. If you look in between the individual instructions, it's actually every instruction is executed one after another. And you can technically interpret this as an unconditional jump to the next instruction. So if we assume that after every instruction, there's an unconditional jump so long as the control flow of the instruction doesn't necessarily change, then we can assume that there is an unconditional jump between every instruction. So if you look at this assembly, for example, you'll see that, you know, we just have a very basic thing. I encourage you to decode the ASCII, by the way. So basically this is just a regular set of instructions. The jump zeros you see here in the middle are essentially the unconditional jumps you don't really see. They go from the instruction one after another. So that's essentially what's going on there. So it's therefore possible to place every single assembly instruction anywhere you want, but only if every instruction is followed by an unconditional jump. Because if you're transposing the assembly and you need to maintain the same code as before, then you're going to have to attach an unconditional jump to every single instruction. So let's see here. As far as one-dimensional arrays are concerned, because we're going to be drawing on a grid, you can technically interpret a one-dimensional grid as a two-dimensional, or a one-dimensional array, I'm sorry. A one-dimensional array is a two-dimensional array. It just requires a little math. You have to multiply by the row or something like that. I can't remember exactly, but it wouldn't, it's not that hard to figure out. So this gives us the ability to interpret an array as an XY grid. So if we have the assembly instructions that have unconditional jumps that can be linked one to another, we can technically draw the instructions on an XY grid and then apply an unconditional jump after every single instruction in order to maintain the same code flow.  So in order to actually accomplish this, you have to follow a few steps. First, you need to disassemble every instruction, because obviously you're trying to figure out what your code is. Then you allocate space and memory a whole lot larger, or at least I prefer like 10 times or something like that than the original code size.  It gives you a lot more room. And for every instruction, you want to turn the FX value. And once you do that, you place the instruction at the corresponding XY location. And then you join the instruction with an unconditional jump, then you mark the memory is executable and you run that. But unfortunately there are a lot of issues that you're going to contend with, like the 6,000-year-old Earth. So like gravity, it only works in theory.  All your jump instructions fucked, your call instructions are fucked, self-referential code is fucked, any code that relies on iteration of individually manipulate the code you're doing, you don't even think about it. So let's start with jump instructions. Since jump instructions are offsets, when they wind up placed in a different location than they were originally, you're not going to point to wherever you thought they were. Because again, like I said earlier, they're offsets. So I mean, if you have a jump instruction right here, and it says, hey, I'm pointing five bytes over here. That's a jump short. And then you move it over here. It says, hey, I'm pointing five, but hey, wait, where'd it go? So you're going to have an issue there. So short jumps are in a similar situation. You may as well just completely ignore short jumps when you're dealing with this, unless it's just not even worth it. Because there's going to be a long distance because of the, especially if you're dealing with a single-dimensional array, there's going to be a lot of issues with, there's going to be a lot of issues with the jump shorts because it's going to be a lot longer than you think it is. Short jumps are easily fixed because all you really have to do is convert them to long jumps. But then after you convert them to long jumps, you have to figure out where the new offsets are.  Because automatically determining where every register is, is going to rely on a lot of knowledge of compiler theory and determining what the register is. Just from reading the code alone can be an issue for all sorts of reasons. It could be changed at run time. It could be a function pointer or it could be a class function pointer or something like that. So unless you're going to want to do a whole bunch of extra work, it's really not worth it. You may as well just ignore it. FFX formulas, when you actually write them, it's not really as elegant as it is on paper. So if you want to do it right, or at least do it well, it's going to require a lot of work because you'll have to do function pointers for your constants. No, not function pointers for your constants, but you'll have to deal with Voodoo of C and C++ in order to figure out your class pointers and things like that. Why do I keep saying class pointers? So here's how you deal with it.  Like I said earlier, it'll make things a whole lot easier for you because you're just dealing with the offsets. Very simple.  Every instruction that you detected has an offset. It needs to be recalculated. This means that you need to keep track of both the instructions and where they're going to be placed, as well as the targets that they're going to be, as well as the targets that they're going to be. So you have to track the instruction that they're pointing at, as well as the individual instruction. And they would probably take me way too long to actually explain how this is, and I don't know how to do it verbosely. So the source code that was supplied with the Defcon CD is basically an implementation that I'm going to demonstrate on stage. So I would suggest that you look at that to figure out how I did it there. After all the instructions are replaced, you're going to want to replace the old offsets with the new offsets. Duh.  So now that we have all the caveats out of the way, let's go with the actual, a more realistic implementation. It's something like this.  Then after that, once you've dealt with all that, write the instructions to the corresponding pointers that you've created, then you're going to want to repair all your conditional jumps, mark the new section of memory as executable, then you run it. And assuming that everything worked out fine and everything is pointing at the right place, weird things happen when this gets all messed up. So yeah, it's just a lot of messed up instructions and bad pointers and you're jumping into really weird locations and memory.  It's pretty awesome, isn't it? So why does this really matter? Is this really just a trick and pony show or is it, you know, doing anything? Like, does this actually do anything useful or does it just look pretty? So the actual utility of this is that once you isolate the assembly instructions and once you actually isolate the assembly instructions, we can put the individual assembly instructions anywhere we want, simply based on a formula rather than having to write an entire function that will likely be fingerprinted by AV or something like that and just be able to write a whole series of mathematical functions that will just draw a whole bunch of assembly onto the code, into memory.  So if you want to perform various polymorphic techniques, you can also use this mathematical formula to do that as well. So instead of having to write your code that manipulates, like I was saying, manipulates your code in a specific way every time, you can write just completely random functions that decide to, yeah, you can write a series of functions and then just have those functions specifically. Yeah, the alcohol is really hitting me now. Wow. It commands it. So instead of writing code, yeah, I already said all that. And remember that anti-reversing isn't specifically about just, you know, finding the really cool, hip, ode, anti-debug techniques. It's really not about doing all of that.    And just walk away. And meanwhile, you'll be able to sell all your bots to the Russian business network, no problem. Because you're just pissing off every reverse engineer that's out there.    It's a game of psychology really.   That's all anti-reversing really is. Sure, it's, you know, it's, there's a technical aspect to it as well. But, you know, you're really just trying to get them away from your code. That's all it really is. So here's what I'm going to do. I'm going to take the obfuscation function and I'm going to obfuscate it. Then I'm going to take the obfuscated version of the obfuscated function and I'm going to obfuscate the obfuscator again. So let's pull up the code. All right, so here is math troll.exe, which essentially contains my sine wave example. You can see, let's see, obfuscate by formula. So here is obfuscate by formula. And you can see the assembly instructions here. You know, they're all in working order and they're going to, they're doing their thing. If you look at the code, it won't help you. This is just the assembly instructions of everything that's been compiled. And you'll notice that I use C++. I'm very sorry. I try to avoid C++ as much as possible. So let's see here. Where did I put that break point? Ah. Right here is where the actual, this is where the obfuscated function is. So once it gets here, it actually, this is going to be the obfuscated function now. So as you can see, the jump instructions have been applied. There's a whole bunch of just different stuff in this buffer that makes it look a whole lot more obfuscated than it really is. And it goes to each and every individual instruction just perfectly fine. And it's, it, I'll show you the shape in just a moment. This is just arbitrarily, I can just hold F8 the whole time or actually I can just run it and it'll still be fine. Yep, there it goes all the way to the end. So the code is still fine and it's, it's now in, there's a bunch of different jump instructions there. So it, it, it looks messed up, but I'll explain why it's not that messed up in a moment. Here's a, oh, oops, wrong direction. Here's a visual representation of what the stack looks like. Every time this happens, I generate a random sine wave formula that will arbitrarily, you know, make a bunch of different shapes, but this is the coolest one of, of the batch. So I decided to put this up. The, I believe the code starts about, can you see my mouse? Yeah. I think it starts about here. I can't remember exactly, but it wraps around and keeps going. And this is basically what you're seeing is the actual code flow. So it goes all the way, you know, it just, it just does a cool sine wave. But I mean, it's not just sine waves. You can also do spirals too. So you can, it, I, and these are really the only two formulas that I included on the source. Like I said, you can do a whole lot of other creative stuff that you want to. And this is, what, what this is essentially is just a diff from the initial buffer and the finish buffer. And it's, it actually just looks exactly like that. And it's surprised, it looks pretty cool to me. But, you know, the issue is that you're using unconditional jumps. So, and that's really bad. Because if you use unconditional jumps, like I said, you're just, the code flow is still exactly the same. Because the unconditional jumps were there to begin with. So if you have the unconditional jumps there, all you really need to do is go from the entry point to the end and get rid of the jump instructions. All you have to do is read those instructions and boom, there you go, you got your code. And it's completely unobfuscated. So, how do you deal with this? Well, the inverse of an unconditional jump is a conditional jump, which goes in two directions, which makes it more awesome. In fact, you could say it's 50% more awesome.  So that's what opaque predicates are for. So for those who don't know, an opaque predicate is essentially a Boolean statement that always evaluates to a specific version no matter what. So let's consider the null space expansion I talked about earlier. If you have a set of instructions and they have unconditional jumps between every instruction, it also follows that a series of assembly instructions which don't have a direct effect on the assembly can be applied. For example, as long as you write very specific instructions that don't modify the underlying assembly of what you're trying to obfuscate, like if you're trying not to mess with registers, then as long as you maintain the state of every assembly instruction, then you're good to go. And this is pretty awesome, too. So you can consider every assembly instruction to be able to be wrapped like this.  And the preamble is essentially what comes before the assembly instruction and the post script is obviously what comes after it. So the preamble section is typically used for two things or it can be used for two things. You can repair the after effects of the previous preamble of the past opaque predicate. The anti-debug code chunks can go in there, too. But the preamble is very limited because you can't really do that much. The post script you can do a whole lot more with because it's actually going into the next instruction, so you don't have to really worry about it that much. So you can do a whole bunch of other stuff as well. So what can this section be used for? You can put opaque predicates and obfuscated jumps to link to the very next section. Anti-debug you can also stick in here, too. General code flow obfuscation, that sort of stuff. Encryption. One of the things that I think would be as really cool is that actually I'm working on it right now is being able to encrypt and decrypt every single instruction so that as every instruction is executed, it decrypts the next section and decrypts the next section and decrypts the next section. Oh, by the way, here's a bunch of anti-debug in the preamble. Oh, I guess you don't get the rest of the code. And there's all sorts of other stuff you can do with that, too. So here's a great example of this. In Green we have our preamble data and a very generic call to isdebugger present, which, you know, all it does is once it figures out that there's a debugger, it gives you the finger and jumps to some random code section that will probably spawn last measure or something awesome like that, who knows. And we have a very simple opaque predicate here at the bottom, you know, you maintain the value of EAX in the post script of the top instruction, ZOR it so that JZ thinks, oh, well, I obviously can go either left or right. I think I'll go right because it's zero.  Then you got the next instruction, et cetera, et cetera, et cetera. So this introduces a whole lot more issues because what you're going to wind up running into is it's going to be really hard to determine which instructions affect which. And there's all sorts of other nonsense.  So, okay, good, no one has schmoo balls, I'm safe. Our FFX formulas also don't necessarily need to be iteratively run. You don't have to do just F1, F2. If you're clever, you can figure out specifically how many instructions you're going to have. And then for every instruction, just F of 27, F of 54, F of 9, and that will essentially place your instructions in random places. And when you do that, depending on how you wrote your code, that will allow you to, I shouldn't have had eyes, that will essentially allow you to determine, man, I shouldn't have had that last shot. Wow. Long a pause, I kind of deserve it. So you can essentially just determine it iteratively and it will still link your instructions. They'll just be completely randomly placed. So if your code is generated from a predictable formula, then it also follows that the entry point is predictable. So you can take this to one level more before you actually wind up getting to your code. You can essentially obfuscate the entry point in some way or another, do a whole like 300 assembly instructions that just gets the entry point.  So there's all sorts of stuff you can do there too. So there are various drawbacks to this as well. So you're, yeah, there are various issues that you're going to be still running into this even though this is pretty cool. So this technique assumes you have highly compiled code.  What am I talking about? Anyway, if this really assumes that you have highly compiled code because as it's disassembling the instructions, it's following a very simple path. So it's not going to assume that there's all sorts of really weird tricks that are going on.  So if you're trying to obfuscate somewhat obfuscated or manipulated assembly, it's not going to work out that well for you.  All the red spaces of code, all the blue space is sure there are things you can do to make it a whole lot more efficient, but there's obviously a whole lot of extra space there that's going to be an issue for you. So it's going to have a massive memory footprint if you want to do it right, or if, yeah, if you want to isolate out the instructions. Yeah, you're dealing with a gigantic data set. So it gets significantly larger when you obfuscate more than just one function. So if you have some really awesome pack or you downloaded from malcode or something like that, well, I really hope it's efficient for you. So function pointers are unpredictably fucked. Sometimes they're good. Sometimes they're not. It really depends on what you're doing. So it's definitely going to be an issue there because you're not going to be able to predict where, when a function pointer is accomplished in assembly, it's usually a register-based instruction like call EAX, call ECX, or an offset to ECX, usually if you're dealing with a C++ class. So they're going to be broken in some way or another. So it's the same way with the C++ STL is usually okay, but sometimes it'll wind up getting fucked. So you're going to have to deal with that. The more clever you get, if you get into the preamble post-script stuff I was talking about, the more you think about it, the more it gets really complicated because, oh, okay, I'm going to push this here and this set here and then, where's the dragon book? I need the dragon book.  All right. Seriously, I should get some food. But anyway, it really becomes a really quick slippery slope from, hey, I can put a jump instruction here, and then you wind up digging through the dragon book for months and months on end trying to figure out what exactly you're doing. So I think I'm pretty short on time, but that's essentially the end of it. I hope you learned something today. I got really drunk, so I'm not sure exactly what happened. So if you, if you want to follow me on Twitter, my, like I said earlier, my Twitter account is Frank Squared. I have a blog and a website. If you like Anzi, it's on my website. So cool. That's my talk. Thank you very much for coming.


People have been talking on the internet about things that they're passionate about, one of which... People have been talking on the internet.  People have been saying things. According to Empire, Indiana Jones 5 will pit India against Nazis again, and it's going to take place in 1969. Perfect time. Is Connie in this? I doubt Connie is in it. If he is, he might be fighting for the wrong side. That's the honest thing. He might be the villain. Although this villain, which is, I never say his name right, Mads Mickelson...  Is that how you say that? Mads Mickelson? Mads Mickelson, so... He looks very similar to the original Nazi villain, so they're kind of doing a throwback to that. Let's read a short synop, which is, of course, short for synopsis. This is a part five, right? This is part five. Okay, gotcha. Empire reveals that Indiana Jones 5 finds our hero in 1969 living against the backdrop of the space race. But the American effort to beat the Russians to the moon brings with it some uncomfortable truths for Indy.  Boom. Bombs dropped. How ex-they are is the question. Okay, so Indy's going to kind of do some digging in, and he's going to find out that, yeah, these assholes aren't done.   That's correct. That's why this is the backdrop, which it's a fascinating backdrop to go with. Hopefully it doesn't turn out that they're aliens at the end. You know, it's like Indiana Jones and the Crystal Skull. Fun fact. What's that? Indiana Jones movie. None of them. None of them. Looks like we both asked some movies to watch. Bruh. Here's a beautiful empire cover where we see Indiana Jones dead. Do you know where he's looking? Do you know what this is? Looks like New York. Is that New York? Yeah, looks like New York. Yeah. So it looks like Indy's going to go to the Big Apple. I wonder if he's going to wear the same clothes, though. It's going to be hot. Well, it's going to be cold, probably. 80-year-old Indy's still in the same wardrobe. Yeah, he's going to dust off that duster. He's got his whip. You see his iconic whip. He's holding onto his hat. I see that, too.  Oh, gosh. Yeah. And then we have the beautiful empire cover where he's looking down. He's very disheveled. Actually, he's not disheveled. He looks pretty clean cut for an 80-year-old. It's got to be his last Indy movie. Did he mention that? He probably said that 20 years ago when he was Shia. This is my last one. This is my last one I'm done. Sorry, princess. I'm not doing any more of these. So, quick question. Is it worth watching the Indy movies? And your personal, do they hold up to right now? No, they don't. Well, the first thing is I'm going to have to watch at least one. It's like watching an old black and white Zorro for the first time. So it's like, yeah. Yeah. So it's like, I get it. Respect. I get what you say. Good job in the day, but yeah. Like, I showed it to my kids relatively young because I feel like in order to get that type of audience, like a new gen, you have to hit them when they're like little kids. I know what you mean. They all like the new fan dangled stuff up there. Yeah. And they're like, yeah. Okay. Cool.  I got to check it out though. I'm probably watching one of them. What's the one with the little Chinese shirt? Short round? Yeah. That's Temple. Temple of Doom. I'll check that one out. That one's the worst. Really? Well, Crystal Skull is the worst, but then Temple. Some people love Temple of Doom. I'm not a big fan. That's the one I know the most. The first one and the third one, the Last Crusade. Last Crusade is fantastic. Okay. Yeah. That one's really good. I'll watch it. I'll have to at least watch one of them before I watch this.