 This morning we have a pre-recorded talk for you. Atlas is going to be talking to us about emulation driven reverse engineering. Please sit back and enjoy. I unfortunately was unable to make it out there this year due to family health issues. But hopefully I'll be back there next year. Thankfully Nikita was kind enough to let me record something and send it out to you. Hopefully you'll enjoy it. Now some of you have seen me speak in the past and if you've seen me talk in the last few years you've noticed that I've talked a lot about emulation. I've talked a lot about symbolic execution and emulation and static analysis for reversing and bug hunting. So today's talk unsurprisingly is about emulation. Today is about emulation driven RE. You'll figure out what that means in a few minutes. Basically how do we let the computer do more of the hard work so you can do more of the fun stuff and not rot your brain? So a little bit about who am I. Many of you know me. I broke out of VMware with an amazing team. I've done a lot of power grid hacking. Generated a tool called RF Cat. I've done a lot of car hacking lately. I'm a vivisect core dev. I've played a lot of capture the flags. Some might say that I'm addicted. More importantly, I am a Jesus follower, a daddy husband and a daddy and a husband. And I'm a principal researcher for the company named Grim. Just to give you a quick refresher before we jump into the fun stuff on emulation. What is emulation? How do you do emulation? Oh my gosh, you're going crazy. Emulation is actually very simple. You have to keep track of registers. You have to keep track of memory. And you have to implement instructions that an architecture would that act on the memory and the registers. You might implement peripherals if you're trying to go a little bit further. I know that QMU and a lot of the emulators that you see definitely do. For our purposes, it's not necessarily always important. Sometimes can help. Sometimes you will also implement system calls and interrupts and handle those. So what does emulation do for us? Well, in many cases, we can write analysis modules using an emulator, a lightweight emulator that can answer questions that might be a lot harder to answer or at least abstract to cover a whole bunch of different circumstances and architectures. You can also use emulator to get immediate context. And I'll show you about that in just a minute, within a function. And basically the answer of the day, emulation does the thing you need it to. So it's like you're creating these little minions that you go off and you tell them to do this thing and they return back with this big milk crate full of junk that may have really awesome stuff and it may have a little bit of craft you got to weed through it or you write your code even more intelligent to weed through it even better. So a little bit more beyond the idea of emulation because you guys have run into emulation before whether it's Game Boy emulation or QMU. Partial emulation is the idea of emulating code that you don't have the full context for. So most emulators that you would run into probably all the emulators you knowingly ran into start at a given point like the start of a binary program or the start of a firmware and you start off and it's got the initialization process and it goes through everything, setting up everything and gee, that sounds a lot like execution and you can debug execution. Partial emulation allows you to get around some of the issues of getting full context by providing things like safe reads and writes. If the emulator runs into a read of memory location that doesn't exist or a write it'll just say let's pretend that that worked. And on a read it'll just give you the correct amount of bytes back of some known value so that you can say oh hey that looks like a lowercase a or a bunch of them. In our case that's what we'll run into for safe reads. We can log reads and writes through an emulation pass. So if you run through a function, emulate through it, you can have all the things that are read to and written to track for you as well as a path that you carved through the, that your emulation pass carved through the function or code. You can also snap in analysis monitors or emulation monitors. Analysis monitor is just a special version of one with a lot of wrapped in goodies. An emulation monitor is simply something that gets to watch as emulation happens and maybe make decisions or at least track information. And we'll talk about that in a few minutes. And then taint tracking. We have the ability, we've got a great taint engine that we can say hey just give me a number, I'm going to shove that number in here and hear that number really means uninitialized register RDX or this argument zero for example. So this kind of feels like baby monitor protocol and in a lot of really amazing ways it is in a good way. Don't be offended. So a few examples of emulation at work. We're going to talk about four specific ones today. Immediate context. We've already gone over it before if you've seen one of my previous talks but it's still so amazing and so easy to use that I got to call it out. We're going to talk about the built-in vivisect i386 calling convention analysis module because it uses analysis monitors. It uses a lot of the emulation stuff that we're talking about. And then we'll go on to a little gizmo that I created and continue to implement on my own called funk recon or function recon. I implemented as a vivisect extension. Vivisect is my tool of choice and it provides a ton of these emulation, partial emulation toys for me. And then at the end, the whole reason that you're here and not at a previous talk is Ninja EMU and how we can use emulators to drive our reverse engineering. So starting off, immediate context. So built-in to vivisect, when you're displaying a function, you can right-click on anywhere in the function and go to the function submenu and there's an option called show emulator state. Basically what's going to happen is when you click on this, vivisect is going to spin up a workspace emulator which has all the bells and whistles with safe reeds and taint tracking and path tracking and all that. And it will say, I'm going to find a path and emulate to this location and what I do, I'm going to spit out the context of that path. So at the bottom of the screen is the output from show emulator state running emulator two and it's that address three two DOE and you can see that right in the function title at the head or on the top showing register magic state at that location stack delta zero, we haven't actually changed the stack at all. Okay, that's good to know. And here's the instruction three T three two DOE is the LD LDR age R2 from a D reference of the R2 register. This is a power PC or I'm sorry, this is an arm function. Now it says I know these operands up operand R2. I know that that is at this emulation point zero X zero eight zero one zero E zero C. And here's the decimal version of it. And the other operand, which is a D reference of the register R2 shows the D references of R2 the same address. It's the same register and it spits back capital A is 41414141. Now the original the original safe reads used to read all capital A as we shifted to lowercase a's for for various reasons. And actually it is set up all now. So this can be wildly beneficial while trying to reverse through a complicated function trying to get an idea of where you've taken an argument and you've added to it and you're subtracted to it and yada, yada, yada down the line. Next example, we're going to talk about the calling dot p y the analysis of the analysis module used for Intel I3D 6, in other words 32 bit functions to identify special things like the arguments to a function call. The local variables that are using a function call, how deep the stack goes and including something cool called mnemonic distribution where it goes through all the instructions in a function and it just tracks how many usage of each are in the function. So if you've got 32 moves, it'll say MOV 32 and any pushes, pops, other reads, writes, XOR, XOR is a pretty interesting one and it just stores that as part of the metadata for the function and which can be very useful particularly when finding interesting things like hash functions, crypto functions, things like that. One example of using emulation in Vivisect on a daily basis is calling convention identification. So for example, what I'm talking about is this function right here, sub020a030 in this code has a number of arguments to it. It is identified as a system 5AMD64 call and has these stack variables identified and we can go through and we can name them as we do analysis. This is all done on Intel 386 for example. We're just going to use this for example. Each of the architectures have their own version. We have an analysis module which starts out as analysis modules do using analyze function. The calling.py has analyze function. We hand in a Vivisect workspace and a function virtual address. It immediately spins up an emulator and this analysis monitor and snaps in the emulation monitor right here and then runs the function. It says run function, here's the virtual address, max hit 1. So do all the paths. If you run into something you've done before, quit. Down here it then calls build function api based on the result of that emulation path. So hands in the workspace, the function address, the emulator itself and the emulator, the emulation monitor. And what we get back from that allows the setting of all the things that Vivisect makes use of. So let's take a look at that build function api. Specifically one of the things that it does is it grabs the number of arguments and it starts off determining that using the emulation monitors tracking of the stack max. What is the maximum stack address that was accessed? Because for Intel 3D6 you put your arguments on the stack so from the base it then you access up from the stack base. So if we end up with more than 40 arguments we think maybe that's a little weird. So we default to Cdeco, the calling convention in i386 so dozens of calling conventions and the compilers all went nuts, thought their stuff was the best. But then if we return using the ret number for Intel that means return but also clear off this much space off the stack because that was arguments. Basically it's the cally cleanup. We have a different way to identify the arg count because that ret bytes, divide that by 4, 32 bits each actually is the number of arguments clear and simple. We then go on to say, hey, any uninitialized registers that are used in the function without an initialization, let's figure that out and identify calling convention from there. Because Cdeco and standard call are very common but there are a whole bunch of derivations off them that add in, handing in arguments in EAX and ECX and yada yada. So we have a dictionary that we look up based on the undefined registers and voila, we got our calling convention and our argument count. All right, next example we're going to talk about is probably code. This is another internal function of Vivisect that heuristically determines what a pointer points to based on particularly looking for executable code. It's part of a family of is probablys and you will show that in just a second. It starts out by spinning up a workspace emulator with partially MU bells and whistles. It attaches an analysis monitor and then emulates every branch. Now one of the cool things about our partial emulation if I didn't mention earlier is the ability to say, hey, we're going to go to a conditional branch. Yeah, let's do both. So I'm going to take one path this time we'll just store off the state over here and then when I'm done doing this path, I'll come back and I'll emulate through that path as well given the same state that we hit right there. Wildly powerful. And so we hand in what's the argument max hit. So sometimes as we're going through a function, we'll get to a loop or we'll get to something where we've we've got a couple different paths that end up in the same place. And as soon as we run into the same opcode twice in the same location that we just say, ah, we're good. We have enough, which allows us to get through all code without triggering the halting problem and using up all the time, all the RAMs, all the resources in the universe. And at the end, make a decision. Is this code? Is it not? So this example of using partial emulation is built in an analysis module for Vivisect proper. I want to take you through the core code here. Analyze pointer is called number places wherever Viv finds a pointer. And it looks first to see if there's already a location specified because at that point you don't care. Is it probably Unicode? It checks to see if it's Unicode or then it checks to see if it's a string and then it calls this isProbablyCode. So isProbablyCode makes use of partial emulation, a Vivisect emulator or a workspace emulator. We hand it in a virtual address, the location that we're looking at to see if it's code. And it does a few simple checks like, hey, is this executable? If not, probably not code. Or is there a function signature? If so, very likely it is. And other things is, have we already run this? We then set down log level so we can emulate through nasty stuff that's not code and not throw error messages everywhere. We then call getEmulator. And since this is the workspace itself, it's calling it on itself. Normally I will name a workspace emulator VW so you'll often see in my code, VW.getEmulator. And it hands in anything that we happen to hand in to isProbablyCode. It then creates this watcher object, which is an analysis module that we'll look at in just a second. We call setEmulationMonitor onto the emulator that we just created. We hand in the watcher. And then we try to run the function. We hand in specifically the virtual address that we want to run. And the max hit. So if you remember, a lot of partial emulation isn't straight through code. It actually says, oh, there's a branch here. Save that for later. We'll run it again later. And we're just going to continue through one branch. And so this is a way of saying emulate everything. But if you run into code you've already run into in some other branch, just stop. Call that an end. And that allows us to actually emulate through every part of code without eating up a ton of time and give relatively good context to each instruction. If we throw an exception, then no, it's not code. So we just store that it's not code. And we then do a check at the end. Hey, watcher, does it look good? Is that code cool? If it is, we store it. If not, we move on. So let's take a look at this watcher, which is an emulation monitor. And it stores a number of different local fields. It has this ability to log anomalies. If something goes weird, we can log anomalies. And then it looks good and is code. But specifically, this emulation monitor has a pre-hook. So before each instruction is emulated, this pre-hook code is run. And so we hand in an emulator. The emulator we're using, we hand in the opcode that we've parsed out and the starting instruction pointer. If our opcode is in our list of bad opcodes. So we've generated a list of bad opcodes that are very, very common when you're looking through firmware or code. And including, like, how do you parse out zeros? How do you parse out all ones? And so we'll hand in, we'll parse that out and we'll get whatever instruction that is. And then we have a list of those we compare against. And if it's a bad op, meaning we're emulating into something that's very likely just all zeros or all ones. And so that's, we throw in an exception there. We then look through and say, hey, have we run into a return in any of the code paths that we've emulated through? If we have, probably pretty good. So done with that. We then grab the location of the current instruction as stored in the Vibesack database. If the type that we run into is not an opcode. Okay, we're done. This is an API built into Vibesack where we'll go through and analyze, does this not actually return? So there are many functions, particularly in libc or windows kernel 32 that legitimately they don't return. Many of them are error codes or exits or things like that where you go here and you're just done. So we work hard to identify and so we store that information, make it available to the API. Is this a no return VA? If it is, then we say, okay, this is known not to return. So we're going to say that it has a return because we want it to look good and that's very likely code again. And then we tell the emulator to stop. So at the end, we call after we've emulated through the function with a max hit of one, as long as it didn't throw an exception. And many times when you have code or if you're trying to emulate things that aren't code, you'll throw an exception. Most often it's just not a valid instruction. And so this will catch most of the things and if not, we ask the watcher, does this look good? It looks good is pretty simple. If it doesn't have a return set or there is bad code, then return false. It doesn't look good. Otherwise, if you have just repetitive of the same instruction, you can end up with what looks like good code but it just really isn't. And so we look through the mnemonic distribution and we do some heuristics here and say, you know, if we're over a certain percentage of one instruction, then that's probably not code too. We're going to just basically reproduce the functionality listed here and it is probably code. And we're going to use an area that came from the hack-a-sat qualifier rounds this year, something from the Russinante authenticator. So I've zeroed in. I've got an interesting function here and I want to know more about it. All right, so I ran the function, max hit one and it completed. Okay, so watcher, these are all the details of watcher. Watcher, it's got the workspace, trivia and hacks. That's actually the address that we handed in. Does it have a return? Yes, it has a return. Yay! It has 27 different instructions. Is there bad code? No. So that looks pretty good. So I wanted to show you that because you create a emulation monitor, you store what's in it, you tell it what to do with it and it drags along behind. So you can write an analysis module that easily straps in an emulation monitor and you let it go and then you get back the results. So here's our mnemonic distribution. Probably one of the coolest things about is the watcher emulation monitor. Okay, the next one we're going to look at is the Funk Recon Vivisect extension that I wrote. It's my way of easily deciding or determining what kinds of things are going on in a given function branch. So oftentimes you'll start off maybe a main function or you'll have a main loop, something deeper down in, but you've got huge amounts of potential functionality and you can get down a rabbit hole really fast and lose complete sight of where you're going and where you've been and what's next. So I wrote function recon so that I can say oh, going through here, I just want to stay right here. Recon of that function, recon of that function, recon of that function and try to get a really fast feeling for what's going on there. So this is part of my own collection, the Icarus collection that I started years ago and given a starting point, a function, we emulate through all the paths and all the function calls and we grab information like strings, chords, functions, immediate pointers and indirect branches, which actually isn't going to be a part of today's demo because that's not ready for you yet. So now let's show you function recon in action. We're going to go back to our Resonante authenticator from Hackasat and I've picked up a function here that's kind of annoying but a lot of stuff going on here. So I'm going to say let's run function recon right here. See that well. Let's magnify this. So okay, so I'm looking through and I see HMAC, I see delete-auth, create-auth, lib-orbital-totip. I'm seeing decrypting protected data. I like that. authdata.bin, that's something that they provided along with the binary. I see unset, I see rb, so we're probably going to be reading something with binary. I see decrypting, using key, decrypted, blah, blah, blah, file and I see error messages. And then I see rollover period and latitude and longitude. We're talking about Hackasat, so that's very, that's to be expected. HMAC key, secret key allow me to make a lot of sense out of this function without actually having to delve into it. I also see that it's importing a number of things including dlopen and dlsim. That's a dynamic library loader and symbol resolver. We also see allocator and a bunch of C++, standard lib, function calls which is probably why I chose this one. fopen, fseq, ftel, rewind, operator new. So those are the imports. And then it goes down and says okay do I recognize any functions that don't start in the name sub underscore which is the default unknown function name. And so we see actually the PLT entries for a lot of these. So I haven't updated the string version as recently as I've updated the non-string version where we can see here are the different strings that are interesting again, the same ones. Here are the imports that are referenced. And again these are I like this better than the text version right now because it just reads nicer. I can select and show things and I can actually drag that into I can drag that into someplace and view what's going on there. Down here looking at the addresses, calling functions. You know what other functions that we saw. And then we've added in since the strings were updated we've added in a search for immediate values. So if there are immediate values that we found during emulation including where we build a pointer. On Intel this isn't as big a deal as the RISC architecture actually almost every other architecture besides Intel. You'll find the code building addresses that are absolute addresses because you've got a fixed instruction set that simply can't store the entire address in the instruction so it'll say okay load this half and then add this half to it or it or whatever. So the emulator will go through that and each point say hey got this number here is it immediate value is 0 is referenced 152 times 1 is 34 kind of like you'd expect and then we've got different smaller numbers. Safe reads will give you in this case it'll give you lowercase a's so hex 61616161 so if we see that that we know that we've read from someplace that we didn't know what to do with it wasn't an existing app or it was trying to reference something built on an argument that wasn't that wasn't legitimate. You'll also see these 4156 values. These represent vivisect emulator taints so at the beginning of at the beginning of an emulator pass the emulator defaults to loading all the things that could hold arguments for a function call with a taint that indicates what it is and all the registers are pre-tainted with a taint that returns oh this is uninitialized ecx or rcx or whatever so as you can see there's a lot of potential value so if you see like the number 1024 or you see the number 8080 or you see the number c00 blah blah blah some error message. These are numbers that just inherently make sense to you once you've been reversing in particular areas long enough and it can make your life a lot easier like 0x70f for example if you're an automotive person. Hey next let's jump on and take a look at vivisection. Vivisection is a huge helper trying to give you all the access to be powerful in emulation and driving your reverse engineering using an emulator so the problem is reversing is couldn't think of a good word it's hard it's tedious it's exhausting yeah it's all these things but I don't want to sound like a wimp because reversing is really fun I get a huge rise out of it it's what gets me up in the morning that making tools that allow reversing to be easier but it can really rot your brain you can get lost down big rabbit trails I just recently had to reverse engineer and do vulnerability research on a modified form of Apache as one of a CTF part of a CTF it was insane brain drain is very real so how do we make tools that allow for great understanding easy setup so that we we can it's a tool that we're not like I'm not sure if I really want to do that heavy no it's easy let's make that easy we want to make it so that it's repeatable something that I don't have to get the program to a certain point with a certain inputs with the debugger and stand on one toe and hold my hand up here and then maybe it might be no I don't want to have to again easy setup I want it to be repeatable easily I want it to limit my brain drain and maybe be a little fun I find it very fun so that's why I'm actually talking about it today so Ninja EMU is a part of vivisection and it basically wraps a workspace emulator that we can get from a vivisectworkspace it provides interactive to debugging kind of like a more intelligent version of GDB I wouldn't go as far as Jeff or one of those full GDB environments but something more along the lines of just giving you what you need at each step along the way so Ninja EMU in addition to this UI allows you to hook function calls and then replace it with Python code so let's say you have a function call into some logging thing in the target binary that you know the arguments you can kind of just write it in so you're not actually stepping into custom focus code or maybe the is fraught with peril like you know things that need a ton of setup and you're like I know what that is I don't need to know how to set it up let's just go we can hook one of the biggest uses that I found is I hook malloc calloc heap malloc all the things that actually you do a memory allocation I hook and I emulate and I've got a basically a special heap implementation that actually doesn't free anything so you end up tracking everything it's not really good for heap grooming but it's amazing for tracking seeing what's going on in a system you can hook system calls like interrupt calls in hex 80 or 2e not a problem in the process of doing all this in order to support all the function calls that I wanted to emulate we've created three primary fake OS kernels we've got the fake win 32 kernel we've got the fake posix kernel for Linux whatever and we've got a raw kernel which basically is just kind of fitting in the kernel space but it's for firmware that doesn't actually have a kernel but it allows us a great deal of flexibility to expand and extend we provide our own heap we provide rudimentary file system ability including the ability to create fake files just by name here's a path here are the bytes that are in that file and some some attributes for the file or we also allow the mapping of a particular file directory a fake directory space and we redirect that into a real directory space in your host operating system so you want to ensure that be warned and be careful right now we don't actually allow that we don't actually protect against directory traversal so if you're if you're reversing something that knows that you're reversing it in the section or in JMU they may be able to do shenanigans so just be warned there's also developed final policies that help you keep from shooting yourself in the foot we also have a fake registry because a lot of times when you're reversing Windows programs a fake registry is pretty important and so you can just stick in your own stuff and satisfy what you need to get by and we also do environment variables because those are very important as well they're all hackery this is not something that's intended to run a enterprise software solution on so please don't bite me if it bites you in the ass and then ninja emu one of the more recent additions is the ability to drive a function graph to walk through emulation through a graph view there are two ways that we do this first of all we've got in process function graph driving which means basically from within vivisect you jump out you drop out to a shell from the same terminal that you started vivisect up in it gives you an ipython or interactive prompt and you set up the ninja emu and you run it from there telling it what function graph name that you want to drive and as you emulate through it will track it through that that function graph the other way is the more massively online multiplayer version either using a Vib server or a shared workspace where they're intended to have many people all sharing a vivisect workspace we are able to set up a follow the leader session from the emu and the follow the leader session then just sends out where it's at at any given point in time and any number of people can follow through follow along with the emulator as it walks through it is a lot of fun a little bit of setup goes a lot a long way so you can start off with basically not knowing anything and just spin up the emulator and walk through you'll have paint tracking you'll have safe reads and writes but as you start zeroing in on important functions you can then have special setup like oh make this the arg list and I want to hand in this string which will generate a heap allocation for it and then put that value into the right location I want to hand in this number and this number you hand in a list and ninja emu sets it all up for you and allows you to just continue to make more and more sense now let's take a look at this 2005 f7c function that I mentioned earlier it did turn out to be very interesting but it's a little bland but let's start off by running function recon on this boy so we don't see a whole heck of a lot calls to calc mem copy malloc and free so pretty generic but if you think about it compared to the last thing that we looked at very limited this isn't really about function recon this is about making sense of what a function does and you're going to have to forgive me because I only have one screen that I can present to you I'm not going to be able to do as good a job showing off just how awesome this is typically I will have three monitors running at the same time so I can do things on one and have my disassembler window completely full screen on another and my emulator window open on another this will be something that you select off of a context menu for a function but for now let's walk you through the old fashion way so for this example a lot of times when I'm using a ninja emulator I am starting to set up just function calls that set up the environment the way that I want this is not necessary but as I dive deeper and I do more I want to set up the call with with function with arguments the way that I want them so if we don't we just jump in we say import vivisaction let's just say our NEMU is vivisaction so we start off you look at the registers are printed here and you recognize these now as being tainted doped if you will this user interface prints out the address the bytes of the address the instruction that we get there and then as a common our first operand because notice that this actually has an operand which is the weirdest thing ever is and this is translating from the taint value because as you can see edx is the actual the full thing is rdx and it is a taint value and so that taint value translates back into uninitialized register rdx so we know that our next thing push rbp which we also helpfully spit out that that's an uninitialized rbp register and now we move rsp into rbp and rsp is initialized but still this is saying our first operand is an uninitialized rbp so let's create some space on the stack which you're not able to see and I'm going to move over because you don't need to see everything going on with the registers all the time do notice that registers that change they get highlighted but I'm just going to drag this off over here like this for a moment so we can see what's going on on this side of the fence oh nothing is going on on this side of the fence why you might ask because I didn't tell it to this is all stuff that's often set up and it will be set up for us as we as we move forward with the release of the section so let's just say yeah we handed an emulator but we didn't actually hand in a gooey funk graph name this is one way to have the emulator drive a function graph around there's another that is more network friendly where you're going to have a shared workspace and dozens of people can follow along with the emulator but I'm not going to demo that for you today that is a part of the video section release coming up though so let's start over again run step the same thing as we had now as we hit enter we notice that our function graph highlighted the next instruction so this allows us to be very emulator driven even if I don't want to pay attention to the emulator I can say you know I'm more interested in the disassembler right now so I'm going to say that's not really that important but I just hit enter into the emulator and it moves on and I'm able to now look through as the code goes through but sometimes looking I'm more looking at patterns in here and sometimes I will miss actual detailed things so sometimes having the emulator forced me to just say oh okay cool going through and actively visually helping me focus and identify what's going on I'm going to call into this get emu to return me an emulator for do the crypto thing decrypt now I did some work for that name we basically just say hey parse this expression and here's a string I could have used the file name plus an offset or sub underscore blah blah blah whatever the name is and it takes that string converts it into an integer then grab me an emulator and set that address as the virtual address that we start let's log reads let's log writes and turn off save them because if it goes wonky and tries to read from some place that I don't want then I actually want to know it so I can come back here and fix this up and then we hand that emulator the workspace emulator into this ninja emulator that's generated here we then read the off data dot bin that I mentioned before and put that into the file if we don't hand in file data because I can hand in a string that is the same thing as the file and then I call this is actually pretty magical ninja emulator has a set up call function then it takes a list of arguments and if it's an integer it'll push that to the right location the stack or the register that's used for this calling convention and file data is actually a string so it's going to call its internal malloc function create some space that ninja emulator manages and shove that string into that space just by handing it in here we then hand in the length of the file data so that's just a number it's going to push that into the register for the second argument we then know that this is a secret key I know it's super secret key and so that is the ninja emulator takes this says this is a string malloc something that's that size plus some buffer space and store this here and then put that address into the appropriate location for the calling convention and then here's a special way of handing in an argument I've labeled it out count and I'm just going to say hey this is a 64 bit value of zeros I could have said I wanted this to malloc out a location because it's going to be handed in by reference so this will call malloc it'll put in the emulator metadata this name out count and give the address so I can do this mortem inspection when I'm done and so that's initialized so I'm just going to go in and do that there so off emu is this thing that I was just showing you the get emu do crypto thing to crypt and I hand it in the workspace and it does the rest and then I do run step so if we if we emulate through boom boom boom boom okay so rdi we're going to store rdi what is rdi rdi is our first heap allocation and we can look at the heap allocations by typing in heap here and our heap dump shows this is what was handed in from the auth data here's our here's our passcode our secret and here's the output buffer that was allocated so if I wanted to talk about more about this later let's just take a look at this looks like something interesting probably is a string so let's just say hey show me that is a string sure enough it's a string there's a whole bunch of functionality that you can use from this horrible command line I apologize in advance it looks horrible we'll keep working on it but we do have a help that gives you the commands including quit and go silent so you don't print out all this memory and register stuff then we can do a back trace we can use the go command to say hey go until this virtual address or go this number of instructions forward then we also have the next instruction so if we go to a call for example and we don't want to actually dive into the call we can just do an I and skip it it'll emulate it it'll actually spit out all the data from the emulation but you won't have to single stop it B means emulate to the next branch instead of again single stopping we can show our stack as we did before but our stack we can do we can control how much of the stack we want to show apparently I ran past the end of the stack because there's not a hundred entries I can create new new heap items just because if I'm emulating through and I run into a thing where I'm like yeah no that's really supposed to be a heap alloc that I need to shove some data in so I can say yeah malloc that give me bytes and it says ok your new chunk is there so now I can say hey make that and that's a string and make that equal to yo dog hello defcon crew boom so now we say what's on the heap ok again let's take a look at that as a string alright so I mean at that point if we if we're like no that really needs to be in rbx right now we can say rbx equals that address and then refresh and now we see rbx is that address and you know if that's the thing that keeps the thing going you can go back and update your starter script but you can also keep going now the beauty is if it doesn't work out and I figure out whoops I screwed up if I have it in the starter script I can just say hey go back to the starter script and then go to this address and it'll boom snap through all the stuff again alright so moving right along so much I want to show you sorry I only have a little bit of time branch ok cool branch I don't care what's going on in this ok I really do care but for the sake of time we do nexty it emulates through the function returns I got a return value huh let's take a look at the heap for a second so in addition to what I type I allocated there there is what looks to be some text some string data let's see the return value that they return let's just use rx string and this is looking very close to what they gave us and the hint for the Resonante Authenticator so that's vivisection guys here is the location of the project it should be released by the end of DEF CON and if you have any questions please feel free to holler anyway what are you waiting for? solve problems with emulation reach out for help if you need it here is how to get a hold of me play around the rest will come and when you get the slides there is a whole bunch of salvage yard stuff thank you very much looking forward to seeing you guys next year