>>So, we had some AV issues. I had a really cool demo, uh, that was gonna be running on Dolphin Emulator. We’re not going to get to see that I don’t think, which sucks because I was going to hack Luigi’s mansion. Maybe we’ll figure it out if we have time. Um, but we’re just going to jump in right now. So, this is “XenoScan, Scanning Memory like a Boss.” ‘Course my remote just stopped working. [laughter] It loves me today guys, sorry. Okay, there we go. So I’m Nick Cano. I’m 24 years old. I wrote the book, uh, “Game Hacking: Developing Autonomous Bots for Online Games.” I’m the CEO and lead engineer at XenoBot, which is where I make and sell my own bots for online games and I’m also a senior security architect at Cylance. So Xeno Scan is an open sourced memory scanner and it’s written using modern C++ with Lua embedded. It’s highly extensible and I wrote it with like, advanced users and automation in mind. A lot of memory scanners out there don’t have that, so that’s kind of what I targeted with this. So you might say “Okay wait, what’s a memory scanner? Is it this thing?” No, that is not a memory scanner. As cool as that looks… I am not that cool. So, this is a memory scanner. Basically, what a memory scanner does is you start a scan with some initial criteria, then you run the scan and it will scan the memory of a remote process looking for anything that matches that criteria. If you found your target, which general means you have one or two addresses, then you’re good to go. You’re done. If not, you keep updating your criteria to reflect changes in the game and then you keep scanning until you’ve narrowed down the list to something you want. So in practice that looks something like this. We have a game and we have 500 health. So we set our criteria to 500 and uint32 let’s say that’s the type of health. And then we do a scan and we get these results back. We have like 12345 results or whatever that are equal to 500. Obviously that’s probably too many. So then we’ll change our health in the game to 450 and when we do that, those values will change accordingly and then we can run a new scan and narrow them down. Some of the values changed to 450 as well. Some didn’t. Some stayed 500. But we narrow it down to the ones that are now 450. Now we still don’t have enough. We still have a couple hundred so we’ll set up our criteria again to where we heal in the game and now we have 550 health. So we’ll set that criteria, scan – boom, we have our final value, our health, we’re done. So in practice, that’s how a memory scanner works and that’s what all of the memory scanners that a lot of you have probably heard of, or seen before, do. I take it a step beyond this, but I just wanted to get this out of the way to say “this is what we have” and we’re going to look at what I’ve added and what I haven’t seen before that I think is cool. So you might be asking “Why another memory scanner?” Well, uh, existing ones, they just don‘t cut it. So their- their source is either closed and you can’t look under the hood, you can’t add your own stuff, or they are extremely messy, hard to understand, outdated and they’re lacking a lot of easy to make features. So there’s a lot of stuff that you can write scripts for in existing memory scanners, but sometimes you don’t want to write a script to do something. You just want it to be there for you and that comes from their lack of vision really. They don’t sit down and say “How can I make this better for people to use?” And they’re designed for beginners. Like Cheat Engine is, like, point and click. You just put in the number, hit next, keep scanning, you have your values, but you can’t really do much with it. You can’t automate it. Which is- if you’re hacking games at a very high level, you want to be able to automate the scanning. You want to be able to throw something open and run scripts against it to find memory and stuff like that. So I went with a focus on that. And so, why am I telling you? Like, why do you care? Well, I think memory scanners are cool and very powerful, even if you’re not hacking games, and we’ll get to that at the end. They can show you how to work with raw memory at the lowest, deepest levels and there’s, like, a very specialized set of, like appsec skills that you need to understand them and make them. Knowing how to pull memory from other processes without crashing them. Knowing how to tell different types of memory apart. Whether it’s readable or not readable, and all that cool stuff you’ll have to do. So we’re going to jump into a technical overview and just look at what the code looks like and then we’ll get to some demos that I hope work. So the languages and tool chain are cmake, C++, LuaJIT, and Git. Git for source control, cmake for building projects and then C++ with embedded LUA using LuaJIT, which is just a just in time compiler. You can see two scripts here. The top one, if you’re compiling on Windows with Visual Studio, you do that, you have a Visual Studio solution, you’ll compile, everything is done. Compiles LuaJIT and everything. If you’re on another system, you have to do- might have to do something, like, on the bottom. You probably don’t have time to, like, memorize this but you can get the slides afterwards, so… And- it’s- there’s no user interface. So instead of having a user interface where you’re gonna click through, you’re gonna write code to do your scans. And this code just reflects the scan that we went through with the diagram a few slides back. It scans for 500, then 450, then 550, waiting for user input in between each scan. Um, and then it just takes the results, serializes them to a table, prints them out and you’re done. So the code is architected into three main projects. There’s the project you can see on the left here called XenoScan Engine. That’s the core scanning code. That’s the heart of the scanner. That’s what knows how to search for certain types of values. Knows how to flip in DNS. Knows how to search for chunks and thread all of that. All the fancy stuff is there. It exposes three things: uh, scan variants, scan target, and a scanner. A scan variant just wraps any type that might- you might be scanning for, so, integers, strings, and everything. Whereas the scanner target is the wrapper for what you’re scanning. So you can scan a windows process, you can scan a game running in an emulator, uh, there’s a lot of different things you’ll be able to scan in the future as that is extended. We’ll get to that as well. And then the scanner that’s exposed is what actually does the scanning. And the project all the way on the right, XenoLua, is just a wrapper around Lua. Lua’s kind of old school, written in C, not really easy to use, so what I’ve done is write a wrapper around that that has a variant system and everything to make it easier to use. And then in the middle you have XenoScanLua which ties everything together like so. There’s C++ code doing object translation of the scanner targets and the scanner, as you can see with the orange lines. And then there’s type translation of the variants. And that C++ level translation then goes and talks to XenoLua and exposes these objects and types to Lua. Now you can see these green connections. The dotted green connections are kind of, um, they’re like indirect connections through Lua so you can see those on either side of the XenoScanLua. What that means is once the values are pushed from C++ into Lua, there’s then a Lua library that wraps them and makes them even cleaner to use. Those are those dotted lines. Then the green lines are the scripts the user will be running and the library itself and they have a green line joining them which means they can talk to each other. And those are running in pure Lua code, which is what is user phasing. If you’re not writing code on the scanner, you’re just using the canner, you’re going to be writing in Lua, which is really ubiquitous in the world of gaming, both for game hacking and actually game dev. So I think- I think it was a good language choice here. So we have general, basic scanning functionality. Uh, we support all the types. So integers of all bitnesses from 8 to 64, both signed and unsigned, as well as 32 bit floating point, 64 bit floating point and strings that can both be single byte or multibyte. And it just- there’s also composable types. So instead of just saying “I want to scan for this integer,” you can say, “Well I’ve torn this part- this game apart before. I know exactly what the structures look like.” And what I’m doing now is I’m automating the process of launching the new version of the game, putting in known values and then scanning for those, to find the new addresses where that stuff is located. So you might make a structure for that that reflects what the actual structure of the thing is in that game. And then you can fill in all the values and it will search for the entire structure. And really what’s beautiful about this is, y’know, 500 might appear in the game a lot of times and 600 might appear in the game a lot of times, but how many times do 500 and 600 appear sequentially back to back, right next to each other. A lot less. So as you make a structure and you compose it, and you set up all your values, you narrow the margin of error when scanning. Taking it from having to do, like, 5 rescans, 6 rescans, to one. So we’re gonna try to do the demo here. So the demo is just this code right here scanning against the little video game that it’s going to pop up. And I don’t have the code open like I planned to because I had to switch laptops. If everything goes as planned, what’s going to happen, it’s going to scan for a structure doing one scan like we just looked at and if it finds the right address it’s gonna overwrite the x and y value of the little object in this game to the finishing value and the game should say “Okay, you’re a winner.” So I’m just gonna run that really quick. One sec. So you can see your game there. When I hit a button it’s gonna start the scan. Ah, you won’t be able to see it because I can’t move everything over to that screen as planned, so sorry about that. So I’m starting the scan now. It’s going to search for the exact same values we just saw, or it’s going to freeze on me... Oh, I’m in the wrong window. Okay running the scan. We’re winner. You can see the green box move to the bottom right there for a second. That was it moving from its starting position to the finishing position. Obviously this is a really contrived game that I threw together just for an example, but it works. And now we need to try and close it when we can barely see. Cool. So on top of that I have put ranges in so that if you don’t know exactly what a value is, but you know- you know it must be between 500 and 1000, then you can just “Okay, between 500 and 1000.” And you can do that by either specifying the type and then inside of the type function putting the range function and the type system will sort that out for you. Or you can say “I have a range” and then put the type first and then put the two values and it will sort that out for you. If you’re doing it in a strongly typed way such as a structure where you’ve already defined all the types you don’t even have to do any of that as you can see in the bottom code block you just say “equals range” and it’s going to figure out the types automatically. There’s also placeholders. So think of this as like a wild card, uh, like dotstar if you’re familiar with RagX, um, where you just put in these empty brackets which is an empty Lua table and what that’s going to do- it’s going to say “I know this is part of the structure and it takes up this much size but I don’t know the value. So when you hit this part of the structure in scanning accept anything, move on the the next thing.” So that might look like this. Um, this is the same as before but our stage is now set to a placeholder. Our level is the same. X is the same., but Y is now a range and max health is now a range. And if we run that demo again, what we should see is that it still works, uh, with those changes. So I’ll go over this really quickly. So we have that little green square on the left. That green square needs to move to the yellow square to win. I forgot to say that last time. So we’re going to do the same scan as before and then we’re gonna pull the first result and overwrite the x and y values of that first result. That’s all we’re going to do. And what should happen there, is it should go to the end as it did before. The thing is, is the first result going to be right? Because now our structure doesn’t have the constraints that it has before- that is had before because we have ranges in there. It allows for more error in there. But if we run it, we see that we still win because even though we lowered our constraints, the constraints with the structure there were still enough to find exactly what we were looking for even though there’s all these graphics going on and all this drawing and all this other state in the game that might just happen to look similar. Sorry. I was supposed to be at this slide when I did that. So- and there’s variable type to values as well. What I mean by that is you don’t have to use strong types like we’ve been talking about. You could specify typemode exact which is what we’ve been talking about and is only what is supported in structures ‘cause if you try to do variable size types in structures, the complexity just blows up. ‘Cause you have to generate a new instance of that structure for every combination of every weak type you have in there. And then you end up with, like, five hundred thousand different ways the structure can look and it just blows up. Can’t sustain. But for everything else if you’re just scanning for a value you can say “typemode tight” which will do other values of similar types. Soi if you say- if you just put 500 in there and you say “typemode tight” it’s gonna do all integer types and floating types. If you do typemode exact it’s only going to do the integer type you specify. If you do typemode loose and you put 500 in there, it’s going to search for 500 as any integral type of any signedness or floating point types or strings that say 500 ‘cause why not. Not sure why you’d want that, but we have it anyways. So- and if you search for a string with typemode tight it will search for it both as wide or single byte. So. Now this is the part of the talk that- this is what I really want to talk about. ‘Cause right now we’ve gone over generic memory scanner stuff. If you’ve hacked games before, everything I just told you, you’re like “oh that’s cool.” The structures are cool, but you can write a script for that. There’s not really anything new. Why the hell are you here? And this is what I want to talk about is data structure detection. So in my book I showed some Cheat Engine scripts to do this and after I wrote the book I was like, wait, why do I have to write a Cheat Engine script to do this? Why don’t I have a memory scanner that does this? So that’s what I set out to do. So we have to make a few assertions first. The first assertion is that a data structure is just a complex interconnected web of pointers. Just pointer pointing here, pointing there, pointing there, pointing there. But each data structure has very specific characteristics and shapes and if we can detect those characteristics and detect those shapes we can detect the entire data structures. Furthermore, a process is just a massive super complex data structure. So if we take the web that is that process and try to sort through it, then we can find all of the data structures which it contains. So I said in the last slide- I said hypothetically you could do this, but it’s not hypothetical anymore because I’ve done it and it looks something like this. So you can see on the top left, first we’re going to scan for all of the valid pointers in the process we’re attached to. Now what I mean by a valid pointer is anything that is a value that looks like a value for valid memory space within that process. So it could be a value that’s not a point and by chance hits valid memory space, but we’re going to use it anyways because we can’t tell the difference. And we’re going to organize those results into a pointer map. The pointer map is this weird thing you can see here, bottom left. So you can think of it as like, just a map of key value pairs where the key is a pointer and the value is a list of pointers that point back to that pointer. So if you take the top example here. We have Ox00010000 and it fans out up into the right and shows all the values that point to that pointer. So once we have these maps, we can then begin to walk them and look at the characteristics of each pointer in this map and see if it looks like a data structure. And if it does, well, we found our data structures right? So for each one we find, we add it to our results map, and then we’re done. Theoretically. So we’re going to talk about class instances ‘cause this is the most simple example of data structure detection ‘cause really a class instance is just a data structure. Um, the assertions we have to make here are that we’re talking about abstract classes where there’s a virtual function table as a first member of the class and that’s basically it. So if we want to find a class like this, um, you see here this blue box? That’s what we’re searching for. That’s the pointer we want. All the way on the left. The blue box needs to be a non-module pointer. If it’s a pointer that falls within the address space of a module, meaning if it’s a pointer that’s in code then it could just be assembly code that’s moving a VF table into place. Assembly code isn’t a class instance so it’s important to make sure it’s a non-module pointer. And this pointer then needs to point to another pointer in read only memory. That’s important because a virtual function table is typically going to exist in read only memory somewhere in the P-header of the module that, uh, instantiates that class. So once we have that something pointing to a read only pointer that’s a non-module pointer that read only pointer should then have an element there that points to an executable pointer which is indicative of a function. So if we have something in read only memory pointing to a function being pointed to by memory on the heap then it’s probably a class instance with a VF table. So this is what the code actually looks like to do that once we have the pointer map, uh, you can’t really take much from it but it can fit in a slide so I wanted to show how like- how condensed it is once it’s actually written out. And we’re gonna do a demo of that. Uh, let me open the code really quick ‘cause I don’t have it open anymore. Oh my god. I don’t have the scroll wheel. Okay, I don’t know if you guys can read that well but let’s just go through it really quickly. So we’re gonna declare a class base. This base is going to have a virtual function called “dostuff” and it’s gonna have a type field that is a uint32. Then we’re going to implement base as one class called “NOP.” That NOP class will set it’s type to NOP. Which you can see at the top in the enum is Ox90 and it’s dostuff function will do nothing, which is really not characteristic of a dostuff function but that’s what it does. Cool. So then we have another class instance called “win.” It’s dostuff function does something different and that is print “I am a winner.” And it’s type is typewin which if we scrolled up we’d see is Ox1337. So what we’re gonna do is we’re gonna run a class instance, uh, data structure scan which looks like this. So the first thing we’re gonna do is we’re gonna find all class instances after running the processes and attaching to it. Once we’ve found all class instances, we’re just going to loop through them. We’re going to find one whose type is Ox90. That’s the instance of our NOP class. When we find that we’re just gonna store its address. We’re going to do the same thing for our win class which is Ox1337. And then we’re gonna come down here and we’re going to overwrite the virtual function table of the NOP instance with the win instance. Now what that’s going to do, if we look at our C++ code again, what’s happening is we’re going to instantiate an instance of each class and call the function “play” which you can see here with NOP. And the play function right about the main function, what it’s going to do, it’s just going to loop forever and it’s gonna say instance dostuff. So our instance of NOP should do nothing when dostuff is executed but our instance of win should print stuff. And as you can see we’re using a NOP instance. So if the scanner works it’s gonna scan this process, replace the virtual function tables, and the NOP class instance will start acting like the win class instance does. So this the window of the program we just looked at in C++ and when I run the scan, if everything works out, this should start spamming “I am a winner.” Right now it’s just looping and calling a dostuff function that just returns and does nothing. Cool. [applause] I haven’t tested anything on this laptop and that was a scary one. So let’s- let’s get a bit more complex. Class instances are pretty basic. There’s three things we have to look for but what- let’s- let’s look for something crazier like a linked list. And let’s look at the STD list implementation just because that’s pretty commonly used in games since they’re written in C++. So as before the blue box on the left is what we’re looking for and that’s a pointer. This pointer must be followed by an integer N. That integer N we’re gonna get to in a minute. That pointer needs to point to something called a node, which you can see just to the right of it. Now a node has two definitions. The first definition, branching off to the bottom, is that it must point forward to something which, when that pointer is incremented, points back to it. Because on a duly linked list you have a forward pointer and a back pointer. So it should point to something, which points back to it, and it should point back to something, so when you increment the pointer that is that node, it should point to something that points back to it again. If it does that we know it’s a node. The next criteria for a node, which are only going to apply to the first node we find, is that if you keep walking the forward pointer as you see here on the right, you just keep going forward, you should eventually end up back at the node you started with because these are circular lists, right? And the amount of steps it takes, the amount of nodes you iterate over, before you get back to your original node, is that integer N we talked about. So what we’re looking for is a pointer followed by an integer N such that that pointer points to a node which when walking the node- the next chain, that N follows the pointer. Okay so this demo’s pretty simple. The C++ code is just we’re going to declare a list of uint32 and we’re gonna fill it with every value from 0 to 100 that is an integer including zero itself and then in a while loop we’re just going to sum all those things. So the sum of everything from 0 to 100 is 5,050 (speaker misspoke). So if the value is not 550, we’re going to print “Oh no. Somebody modified our list.” So the code looks like this. We’re gonna look for all instances of STD list after running the application, then we’re gonna loop through them and look for a list which has an item count of 101, because we have every value from 0 to 100, so there’s 101 values. Once we find, that we’re just gonna store the list header in a variable and then we’re gonna move on. We’re gonna take that list header, we’re gonna read memory from it, which is gonna give us a pointer to our first node. Once we have the pointer to our first node we’re gonna overwrite the memory 8 bytes past the start, so at 0 to 4 is the pointer to the next node, at- or 0 to 3- at 4 to 7 is the pointer to previous node, so starting at 8 is the value in that list node. So if we overwrite the value at 8 with a uint32 of one we’ve just changed 0 to 1 and the program should start saying that something modified the list. So this our window and as you can see it’s behaving normally, which is that it’s doing nothing, because the list is summing to exactly what is expects the list to sum to. But if I go ahead and run the scan we’re able to pull all lists out of memory, find the one just based on its size, no other information, and then overwrite a value in it and completely change the behavior of the program. [applause] Thank you. Okay. So now we’re going to move on to the one that really gave me hell. So up until recently, when I’ve moved and got worse internet, this project was completely done on a live stream where I stream myself coding, small webcam in the corner, stream the dev and I could talk to people and tell them why I’m doing stuff. WHen coding this on the live stream, I was completely unresponsive to anyone in chat. I was melting into my hands. I was trying to figure it out. I actually had some screenshots but there would have taken up too much time. But this one really messed with my head, ‘cause you can know the theory, you can know exactly what a binary tree looks like, right? You can know exactly how the pointer should interact, but since the structure’s so complex you’re gonna end up in these loops and these chains of pointers which look like binary trees but aren’t and loop infinitely until you run out of stack space. ANd it was really a pain. So I consider myself a pretty good coder and if I could barely get this code working, I definitely can’t get a diagram made for it because I’m terrible at making diagrams. So we don’t have a diagram like before. We have all of this text. What it boils down to is that an STD map, which is a binary tree underneath, can be defined as something that has a parent node or a root node and that node has a parent which, when you point to its parents parent, is itself. So the root node is basically like Fry from Futurama. It’s its own grandparent. If you find a node that is its own grandparent, you know that’s the parent node. Then you want to walk every single node from the parent node left and right. So each node has a left pointer, a right pointer, and a parent pointer. You want to walk every discoverable pointer from something that seems to be a valid root node and it must- each one must follow some criteria. Now there’s a lot of criteria here. For instance, there can be a one node tree which is just a root node by itself and you can see this second line of code where the first indented line of code shows how we detect that. The node can also be in a two node tree that is left heavy. That means we have our root node and then it points to the left side to one more node. That node then is going to point back to the root node on its left and right to mark that it’s the end of the tree. And you could also have a right heavy two node tree which is the same thing but on the right side. In addition, you can have a node that’s at the bottom of a tree, so each side points back to the root node but it’s parent is not the root node. All of that’s defined here. Or you could have a regular node. And a regular node is defined as something which has a parent which points back to it on either the left or the right and it has at least one left or right that is not the root node, because if both left and right pointed to the root node it would be at the bottom of the tree. Um, so if actually any two of those three are correct,then it’s just a normal node. So then the tree is valid if a root node exists and if every discoverable node from the root node is a valid node, which we’ve just discussed, but on top of that if every discoverable node is unique. So if we walk the tree how you expect to walk a tree, which is recursively left right left right left right until you hit the root node at the bottom of each side, no node should be discovered twice. There should be no looping pointers and if there is that’s gonna get you into this crazy loop where you loop forever and it runs out of memory and crashes your memory scanner. So that’s not good. So we’re just gonna look at what this actually looks like. So I think you guys can see this pretty well. We’re gonna define a map where the key is a 32 bit integer and the value is a string. Then we’re gonna fill that map consecutively with integer keys 1 through 5 and string values 1 through 5 such that the strong names of the numbers are the value associated with their integer key. Then we’re just gonna loop through it, clear the screen, and then just print the entire contents of the map out to, uh, the console and then sleep for a bit and do that again. I might actually increase the text size on this window really quick so that it can be seen better. Or not ‘cause my console’s being dumb. Sorry. So I’m really not sure- I guess you probably can read this and it’s doing exactly as we said. It’s printing out the value followed by its key so we have one one, two two, and so on all the way to five. So if we look at our code what we’re gonna do is we’re gonna search for all map instances and then we’re gonna loop through all of the found map instances until we find one which has a length of five. Once we’ve found one with a length of five, we’re then going to store that pointer and then we’re gonna iterate over it, just walking the tree left and right recursively and we’re gonna rewrite the nodes with some other text, uh, then what they currently have so, let me find my mouse. So the window’s up there so I’m going to run the script now. So we replace the text, uh, even though we’re using an STD string inside of an STD map we were able to just know that it’s in an STD map, know its size, and then go in there and completely replace the text even though it’s running in another application. [applause] So now we’re going to get to extensibility. And I’m- this is sad because I have ten minutes left which means I have no way to get this demo working, but one of the points of this memory scanner was that I wanted it to be extensible. I don’t want a memory scanner where, oh, a new, like, games are starting to pop up on Linux or games are starting to pop up on Mac or Android games just became a thing. Well you can’t use Cheat Engine on it until the guy updates it, however long, right? I want it to be so just a few lines of codes and this can run on anything and not necessarily memory. It’s a memory scanner but when I went into this I realized it doesn’t need to be just a memory scanner. So we have this interface, you have four public functions, two protected functions, and a couple of protected variables. Anything that you can implement this properly for, it can scan ‘cause all of the scanner logic lives outside of this and relies on only these functions and values. So the example that I’ve done here is I’ve taken Dolphin Emulator, which runs GameCube and Wii games, and I’ve put in Luigi’s Mansion and I’ve implemented this for Dolphin. You’d see a demo right now but it’s not here. Basically what I’ve done is I’ve patched Dolphin to have a shared memory segment where it allocates all the memory for the game and then I acquire that shared memory segment in my implementation of that interface and then scan through it knowing like, what the mapping looks like. We can find stuff. So if I had the demo here the first thing I’d do is show Luigi losing health and then I’d freeze the health at 100 and you’d see he won’t lose health anymore and then I’d freeze it at 101 ‘cause why not? If we can do 100 we can do 101. And he’d have these wings that were like hearts, just hearts flying out of his back looking like angel wings because that’s the animation the game makes when you lose health and it keeps trying to decrease his health from 101 but the scanner’s overwriting it with 100 every time. So it kind of looks funny to play on. And then I was going to change it to 1337 and when it gets that high the screen completely trips out. There’s a little heart in the corner that’s supposed to be your health. It grows to the size of the screen and it’s just beating and there’s like this pink flashing going on like I guess Luigi was like “I have so much f***ing health. I’m gonna go rave.” So that would have been great and I figured that would be a demo that would carry this talk, but sadly we don’t have it. I’ll put a video online with the slides, uh, afterwards. So future work. I want to add a lot of stuff. So targets for OSX and Linux where we just implement that same interface but for these different operating systems and, theoretically, it should compile. We’re using cmake. We’re using nothing Windows specific except for in the Windows scanner target, so if we add targets for OSS and Linux- OSX and Linux, everything should work so I want to do that. On top of that, I want to add targets for all major emulator types and for memory dump files because like I said before, we can scan anything that is bytes. Why limit ourselves to processes? I also want to add symbolic execution. So what some games will do is they’ll store your health in a variable and that variable will be XOR’ed against another value in another variable somewhere in global memory or in the heap, right? And what that looks like is if you try to scan for your health, you try to scan for 500, 450, 550, you’re not going to find it because it’s encrypted with just a single integer XOR cypher. And it doesn’t work. Right? And that’s pretty common because XOR is so fast. You can do that and mess with the noobs who don’t know what they’re doing. So what I want to do is be able to go through the assembly and find patterns like that where we have a XOR followed by a XOR of another value, make the scanner take that into account, and when it does the scanning, XOR the two together instead of just saying “this address has this value,” it’ll say “these two addresses, when this XOR operation is applied, has the value you want.” So I have some prototypes for that, but it’s nothing great and it kind of breaks extensibility because I’d need disassembly for all the different architectures and stuff. Don’t have that yet. I want to add it. And then I want to add native support for strings of fixed length which- within structures. Structures are only integers right now. Um, you can hack it together in Lua pretty easily using placeholders to just hold the place of the string pointer and verify it after the fact, but it’s not there. Um, and, native support for pointers within strings. Stuff like that. So a lot of you here are like “Look, dude, this is DefCon. My company sent me here. Hacking games is fun, but I don’t do it. I- I have work to do. How does this apply to me?” How can you use this? How can I use this is my normal day to day life? So if you’re reverse engineering, I find this helps me a lot because I don’t have to focus on figuring out what the relationships in the data are and what values are related. I can use the data structure detection to just tell me that and once I have that information it makes reversing it easier. Instead of going in Ida and saying “Okay, all these pointers are being followed. Kind of looks like a map. Now I have to somehow pull all the values out.” Memory scanner does it for you. Helps. Um, and it’s also great for just getting this hard to grasp glimpse of how the program is architected and designed which can be hard to get from assembly code sometimes. So just seeing how all the data’s interconnected and where the values live can help out there. For offense, you can really just say “Screw the Lua” and just take the XenoScan engine library which stands alone and embed it in an application. If you’re a bad guy or you’re red teaming or whatever and you want to steal passwords out of a browser or a password manager or steal cookies or whatever, you don’t have to write your own memory scanner. You embed this thing. You search for things that you know are going to be there or just search for data structures and then look at them and pull the values out instead of dumping all the memory and exfiling entire processes memory over the network which can be expensive. You can embed a memory scanner that’s going to make that job much easier. Um, and it’s great for research too. WHich kind of goes back to reverse engineering where it helps you focus on what the applications are doing aside from the data ‘cause anything you reverse engineer. Anything you research. You have to focus a lot on how the data is connected. But if you could forget about that, you could focus on the algorithms that are changing and mutating that data. So I find it helpful there too. So the code’s right here on GitHub. Completely open source. When I get good internet, I will go back to streaming on dev. I would love contributions from anyone who is probably a better C++ programmer than I am. Um, the slides will go up after the Con at XenoScan slides. Uh, you can probably just take down github.com/nickcano and find everything through there. Me, I’m at NickCano93 on Twitter. GitHub.com/NickCano. NoStarch.com/GameHacking is where you can find my book or you can pick it up at the No Starch booth ‘cause I will be signing after this talk. Thank you so much DefCon. You’ve been awesome. [applause]