 Our next speaker, Rick Housley, he's going to talk about a reverse engineering embedded systems and memory mapped IO accesses with Ghidra. So take it away. All right, awesome. Good afternoon guys. Like he said, my name is Rick Housley. I'm gonna be talking about Perch and as he mentioned it's a Ghidra plugin for adding some memory mapped IO functionality. Right now I work at United Technologies. I'm part of the product security red team on aviation platforms. Previous to that, I worked at Redblown Security where I did a whole bunch of electromagnetic fall injection research and more recently, Thring-Greacrat, the big Cisco route of trust disclosure. And actually if you stick around in like an hour, John is going to be talking about that. All right, so what are we going to see today? We're going to do a quick review of Ghidra for those of you who aren't as familiar. We'll talk a little bit about memory mapped IO and why diversity is actually really painful in this regard. You know, the current methods and tools for, you know, reverse engineering hardware and dealing with peripherals right now and then kind of the solutions that I came up to solve that. I'll briefly mention formal grammar and we'll see how it's actually really cool. And despite having formal in the name, it's not quite as scary. And then at some point I'll hopefully show a working demo and talk about extending the extension and some of the future work that can come out of tools like this. All right, so cool. Ghidra, for those of you who have never heard of Ghidra, Ghidra is NSA's kind of open source, now open source equivalent of Ida Pro. It's really great and really cool in that it has a full decompiler built in. It supports a whole bunch of processors and it has a really fantastic scripting and plug-in architecture that allows you to augment it instead of bugging ill-talk about something new. So this is what it looks like. It was released in March. Also it has Undo, which is kind of magical, even though Ida now apparently has Undo. So this is what it looks like, a typical view of it. You have your disassembly. You have your, you know, your typical graph view that you see in Ida. And then like I mentioned, a really great feature is the decompiler that it has as well. I'm not going to really dive into the basics of Ghidra, but if you're interested and want to jump in, I would highly recommend this talk from Alexi and Jeremy. They do a really great job of kind of easing that learning curve into developing and reverse engineering with Ghidra. What I'm going to talk about is this new window that's an add-on. It's called Perch. And that allows you to kind of explore black box hardware and their kind of peripheral interactions. But before we see that demo and how that works, let's talk a little bit about memory mapped IO. So unlike, you know, typical OS reverse engineering, when you're dealing with embedded systems, you often really care about the peripherals. And those peripherals are often mapped directly in memory. So, you know, the processor and IO devices are mapped using memory addresses. So if you want to flip a pin, you're going to write to some address in memory. If you want to set up some peripherals for SPI or your interactions, those are all just directly in memory that you need to write to or read from. So this is what memory maps look like when you're reading tons and tons of data sheets. And the one thing that I really want to point out here is that these are both STM32s, the same, you know, family-ish, and they have completely different memory maps. And that's kind of where this complexity and why memory mapped IO is really hard when you use tools like Ghidra or IDA is they have a really great support for the core. They have, you know, all the disassembly for ARM and PowerPC and everything like that. But then when you're dealing with these different peripherals that are being written to, they can't support every single processor. And so what you end up having is just a really poorly kind of shown peripheral interactions in firmware. And we're going to take a look at that right here. So this is actually the firmware you're going to be seeing is some Vaporware. It's some IoT VAPE firmware. So it's using this little NRF ARM core. And this is what it kind of looks like in IDA when you first start scrolling through, when you first open it up. And what you see here is, well, really nothing is kind of the problem. It's really hard to tell what's going on. So the first thing that you'd want to do is you want to go open up that datasheet, finds their kind of memory map and start augmenting Ghidra's memory mapping, where you add the peripheral chunks. And now after that, Ghidra is going to start recognizing, all right, this is an address in the peripheral region. But this is still pretty useless. So you see up top, it's loading or writing to some address up to the four C thousand range. And so then run back to the datasheet, read, you know, get 60 pages, find your memory map, and then you say, all right, cool, this is dealing with a temperature sensor that's built into this chip. And then for every single one of these, so then you can go label that, find all the registers, label all those registers. And you know, there's, you know, dozens per each one of these peripherals. So it kind of becomes a major pain to do this for one thing. And then when you get a new project, or you want to start something new, you have to do all over again. And then you have to do it all over again every time. And it's kind of a pain. And somebody very smart realized on the Ghidra GitHub, they're like, Hey, for ARM chips, there's this great thing called an SVD file. And what an SVD file is, is it's just a description of all the peripherals for a certain processor. And so they're like, Hey, somebody should write a parser, and parse this format, and then augment Ghidra with it. And, and somebody beat me to that. And that was Thomas Roth, who's speaking next. And he released this loader, which is essentially perched for, for ARM things. Now, unfortunately, and I would check this out, this is open source and available right now, unlike perch, which is going through open source review. But unfortunately, I don't always have the privilege of working with ARM stuff. Sometimes I have to work with kind of random architectures and power PC. And these SVD files are not created for things other than ARM, and they're not available from the manufacturer. So I kind of need a different solution than the SVD parser that Thomas Roth supplies. So on a site side tangent, back when I was working on RedBloom doing some development, we use this amazing tool called a lotterbok. This is the lotterbok trace 32 software. And it's really expensive, but it's expensive for a reason. And that's because it has amazing support for everything. It's a JTAG to plug it in. You can step through all your instructions. And there's this one magical little window where at any given point, you can just see all of the peripherals and you know what's going on in them. And it's just it's really clean and nice. And this is something you kind of write off as like, Oh, that's just cool. But then when you're using tools like GEDRA, you're like, wait, I want that. But in GEDRA. And like I said, they support lotterbok supports pretty much every processor. There's a 942 supported families. That includes, you know, all your ARM chips that NRF chip, you know, power PC, everything. And I say families because memory map diode change is not just in your family, but from processor to processor within a family. So this includes if you have a family, all of those other sub processors within that family, that whole STM32F, whatever line underneath it as well. So how does lotterbok do it? How do they have all this support? Well, they painstakingly work with the manufacturers to create these peripheral files. And this is what a peripheral file looks like, a little similar to the SVD ones, but a lot more painful actually. But they have great support of even at the bit level for inner register what each bit means. These are massive, you know, 100,000 lines of really structured text. And unfortunately, they do some wonky stuff too. I don't know if you can see this here, but they decide to have like fully evaluatable expressions built into this document. So that's where this tool comes in. So what is Perch? It's this peripheral file conversion helper tool that integrates with Ghedra. It takes that peripheral file, you know, massive 100,000 line file. It then parses that file using some formal grammar. And then, you know, you can run some, if you're interested in certain peripherals, you can filter those out, that kind of thing. It translates it into intermediary, and then you can load that into Ghedra. Hopefully at some point you could also load that into Ida and augment it that way. All right, I mentioned formal grammars. So this is the how the parsing works. So because this file is heavily nested, doing a kind of line by line approach parsing, I kind of needed a better way of doing that. And I found that formal grammars are fantastic for this, and you basically take this specification from, you know, LotRBox PDFs, and then you load that into this kind of form you see on the left, which just kind of describes all the different possibilities in a line. And then that gets you generate a parsing, a parser from their parsing engine, and then you end up with a syntax tree. And then you can have an interpreter go and run through the syntax tree and generate kind of the, that intermediary representation for Ghedra after that. So you see this input line on the left. It's some of that crazy math that they love putting in all their files. And then it converts that down all down to that tree and then interpret this and evaluate it to actually just the number that it's supposed to be and then go and label that in Ghedra. All right, so that's, I think, enough talking for now. I'm going to show you a little bit about what Perch actually looks like in Ghedra. And we're going to start off actually in the same spot that I had shown you earlier with that vape firmware in that temperature sensor region. So, oh, this is hard. Yeah, that's the right one. Let me see if I can mirror here. Maybe not. All right, so what you see here is you see Perch on the left. And this is a peripheral tree of all of the different peripherals that are included in the NRF firmware. I mean, the NRF chip, sorry. And so we can navigate this tree and you'll see that these are all the peripherals and it's colored by utilization. And so let's jump to, well, what was my good example? So the MPU, for example. In this, that's kind of neat actually from a security perspective. Disable protection mechanisms in debug mode. Cool. So what we can do is we can just follow that to where that's written. And you can see it's kind of now cleanly written in memory or in a disassembly here. And so we can walk through all these different peripherals and start to get a really high level idea of what certain functions are doing. Initially, if you were to look at this function, just see a bunch of data accesses. But now you see, okay, this is actually setting up some clock stuff. Let's see, what was one of the good examples? So you can see, all right, this is the function that's setting up and starting the watchdog and all that fun stuff here. And then another, from like a very high level perspective, this vape, I don't own this vape, I just have the firmware. And so I really wanted to be able to see, okay, so what is the even hardware look like? And you can get a really quick idea of like, all right, well, they're not using SPI for anything. They are using the temperature sensor. You can go, oh, I wonder if they're using the temperature sensor for the actual vape product or what have you. So that's Perch and a nutshell in terms of demo me. Here's some, you know, great examples as well of what's happening behind me. You know, the RNG getting set up. And so what comes after this? All right, cool. So this is that, the cleaned up Perch version of that initial shot that I showed you. Some of the features that it supports, the short and long register descriptions, so you can really cleanly see like you saw. All of those, those axisies, the tree hierarchy is actually really nice because Lauterbach does a great job of nesting peripherals. So in, well, in some cases, you'll have, you know, debug registers nested with another debugging for some specific sub peripheral. And then like I mentioned, the colorization is really helpful for seeing kind of a high level overview. It's what, what is happening in. Okay. So now that we have this, other than helping with, you know, general reverse engineering efforts, what kind of like other things now that we have this new layer in Ghidra can we do? And what's great about Ghidra is you have these plugins. This is a plugin or extension, and then you could script on top of them as well. So one of the scripts that I developed that is now on top of the perch layer is finding setup functions. So a really quick heuristic for finding a setup function is you see, all right, I want the one function that does the maximum number of rights to a peripheral family, right? So SPI flash you'll say. Let's find the function that sets that up. Go through all the different functions and find the one with all the rights to that peripheral. And so you can immediately label in Ghidra all of the different setup functions for all the different peripherals really quickly. What else can you kind of do with this kind of infrastructure built in? So this is a terrible picture of a control flow graph that you'll pretty normally see in something like IDIF or, you know, and Ghidra in a really terrible view. But what you can do now is you can also add in your peripheral interactions. So in this diagram when you see all of the colored dots are the peripherals, and you can start to immediately notice, like see this tree over here, that's pretty obviously a setup function. And I actually have a better shot of this next one. You can find some really interesting stuff, like this is the radio, and it's also looking at like one time program of memory. So, hey, is this doing some key stuff? Is it just setting up the ID, that kind of thing? And this is without looking at a single line of disassembly, you can start getting these kind of insights, which is something I enjoy. All right. So what should you walk away thinking after this brief little talk here? Memorymap.io is kind of a hard thing to deal with given the massive diversity of all these processors. Fortunately, tools like Thomas Roth's SVD parser and Perch are hopefully going to make that a lot easier. Thomas Roth's tool is available today. You can find it on Twitter. Perch is going through open source review, so that will be also available. Those peripheral files I mentioned are also entirely available on Lauterbach's website. They're not proprietary. You don't have to buy their equipment to access them, and they're for now still online. The kind of general big picture things that I think you should take away is the value in Ghidra is more than it just being a cool hardware versus engineering tool that's pretty equivalent to Ida. It's actually, in my opinion, the ability to extend it so much further, and it's really well documented foundation. It's just great bones to add on to from a reverse engineer's perspective. And then you can do some pretty neat stuff with graphing outside of Ghidra and get pretty cool insights without touching the assembly. I didn't really talk that much about it, but formal grammars, I do want to give them a shout out, are a lot less scary than they seem, and they're incredibly useful for doing large text parsing quickly and accurately. And yeah, I think that sums it up. If anybody has any questions, please let me know, or if you want to know what this spirally thing is, find me, well I guess, in the beer garden after. All right, let's think quick. And we'll do Q&A as usual outside.