The Hackers Guide to Hardware Debugging: Matthew Alt

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
well hello everyone my name is bruce dominguez welcome to remotacon uh i hope you're having a good morning good afternoon or good evening wherever you may be and uh just fyi you can always post uh questions or comments in the group chat and respond to each other give each other feedback uh because that's what makes this community awesome and today we'll be joined by matthew alt and he'll be hosting a discussion on hardware debugging matthew is a reverse engineer with a focus on embedded systems uh he began working in the security industry for audible automobile performance and searching for vulnerabilities in uh engine control units and diagnostics implementations matthew currently works as a security researcher and as a trainer and consultant and he regularly posts projects to his github rongbod.github.io uh and with that uh matthew uh thank you for being with us yeah uh thanks for having me i see some familiar names in chat from the guidera course so uh those of you kind of know what you're getting into um as we you know go through these slides and work through uh what we're gonna work through on the hardware bench uh please feel free to ask questions and i'll get to them you know as soon as i can and kind of like they said before definitely open for you know having discussions about this and you know getting like a back and forth going so uh with uh with all that to say let's get started so the already got an introduction so we'll burn right through that um we're going to talk about like the overview and goals of the session what you know we want to try to learn what we want to try to do we're going to review you know what single wire debugging is and do a few exercises on it on the xbox controller that we have over here and then we're actually going to talk about dfu mode which i know we didn't mention in the project but found a nice little easter egg with this controller while trying to debug something after i bricked it and so we're going to talk about that which uh is pretty interesting and then if we have enough time we're gonna go over jtag at a pretty low level and show how to use that on an ssd that i have here on the bench and so yeah as they said before i'm matthew alt uh i post stuff under wrongbod and i'm a security researcher so we already talked through that we don't have to do that anymore um and so yeah the purpose of this workshop and this session is to explain to you how you know hardware debugging works and also show you how to interface with it using you know open source tools both software and hardware and so as we go through this we're going to take a look at two different targets an xbox one controller and a transcend ssd if we get enough time and so what i want everyone to get from this and what some of the takeaways i hope are or that you folks learn how to under like identify these ports when you look at them on a pcb and also understand kind of the core components that make up how a hardware debugger works so the use case being you know if you plug in all your tools and you hit the button and maybe it doesn't immediately work i'm hoping that after this you'll have an idea of where to go to figure out maybe how to tweak things to to get things to work properly because anyone that's tried to use you know open ocd or any kind of jtag software you know that sometimes there are quirks sometimes it works sometimes it doesn't and it's kind of hard to get down in the weeds and tweak things and figure out how to make it work for your particular target and so we're going to go through how to use you know openocd and your jtag to look at some of these ports and with the ultimate end goal of pulling firmware off of them uh reflashing that and then even doing you know single step debugging through gdp so the first platform we're going to take a look at is an xbox one controller we posted a link to that up on the hackaday i o page and the goal for this we want to extract ram flash and rewrite that flash and we'll talk about what protocols this target uses later on the second platform if we get a chance to look at it is let me move my i was asked to move my video up is that better i can make it smaller too um the second platform is this ssd and the goal of that is going to be to identify the jtag pins extract ram via jtag look for any data of interest in that dump and then take a look at how this thing behaves when you issue certain reset commands because it actually has some pretty interesting features in it as well and so this first platform this xbox one controller i'm going to flip over to the hardware view real quick for those of you that have one or those who that don't you can follow along here so we've got this xbox one controller now as you can see we've got you know a couple of epoxy blobs here probably covering the main cpu if you look at it closely you can see that there is a debug header right here and i've got some uh header pins soldered to that and in addition to that we've got another ic here we've got some pads for what looked to be you know an soi c8 chip so whether that might be an it could have been an additional eprom or something we're not sure there are multiple test pads throughout this thing that are labeled you know with different buttons that they can press or just you know tp and then a number um and so to give you a better view actually of the debug header i'm going to put it under the microscope and get that cable out of the way and so give me bear with me folks all right here we go yeah so here's our debug header let me get that in better focus yeah okay so we can even see looking at this header that if you look at it mirrored it would say swd and so some of these pins on this header are labeled this one the first one is not and then we have res a14 a13 and 3v3 and so those of you that have looked at you know this kind of hardware before that's kind of an immediate indicator of something that you might want to start digging into um and so with that let's jump back to the slides here and so after taking a look at that right the core components that we see are you know this what is probably the cpu that's covered in epoxy we've got you know a labeled usb connection down here there's this additional sound chip here we've got you know this debug header that we just took a look at and then these pads for um you know what could be an eeprom or an additional some additional peripheral chip that may be used and my hypothesis is that this was used for the same design was probably also used for xbox 360 where they had an additional chip that would actually issue a challenge response over usb to authenticate with the xbox so with that um you know what can we infer from taking a look at this pcb well we don't know what the cpu is right because it's covered in this epoxy so we're already kind of in the dark which really isn't where we want to be as reverse engineers right you at least want to find a you know a part number or something you google and grab a data sheet but we're kind of already deep in the woods here um that ak-495 chip is actually an audio processing chip and so we'll go back real quick that's uh this chip right here and you know when you're looking at a pcb like this it's kind of easy or it can be easy to infer you know functionality based on the location on whatever the target is right so we have the headphone jack right here and then right next to that we have this audio amplification chip and so as i said before that other pad or set of pads is likely left over from you know the design for the xbox 360 controller most likely from the same brand that was used for this external authentication i see and so this debug header that we identified this guy right here is probably our best bet right for learning more about you know how this target works or what components it might be used all right so if you know we can examine we examine those header pins and what can we determine about those from the silk screen right we looked at it we saw that one of them was labeled 3v3 that's probably voltage one of them was labeled res there's a really good chance that that is going to be used for a reset line because it's pretty often when you have you know hardware level debugging you're going to have a hard reset line somewhere near the pins that you're using for that and so we can take a look at what this device looks like when we actually plug it in to the pi so let's do that really quick so i'm gonna go to uh terminal on the raspberry pi here and we're just gonna run d message and plug this controller in so we plug it in okay cool so as one would expect right it just shows up as a standard usb device um typical hid device you see we've got serial number manufacturer string and then the product description as well you'll notice the manufacturer string is a little messed up and we'll explain why that is a little later and so matt this is actually a custom image that i put together uh for the raspberry pi that presents itself as a present itself as an ethernet device to your host and then you can go through and access these tools from there but this is the same thing you would have if you were at a uh just a terminal on the pi but having it accessible through the browser makes life a little easy and so if we jump back so if we look at the voltage levels across uh the five pins that we have we have you know the first pin which we assume is probably ground right is zero volts the next pin which is the reset line is 3.3 volts the third pin in the list is floating at 0.1 volts the third is at 3.3 and the fourth is also at 3.3 which makes sense right because it was labeled 3.3 volts and so when we're looking at something like this right you want to always make sure that you're aware of what your logic levels are and the logic levels of whatever it is you're trying to interface with it and so we're going to be interfacing this controller with the pi they share the same logic level so they're both the 3.3 so we don't have to worry about any kind of level shifting or anything like that and so if we look at these pins if we monitor monitor them on boot with a logic analyzer there's no data going across them they just remain at the same voltage and so the reason we would want to check something like that is because it could be you know potentially a uart or some other kind of you know debug console and so you know how does this thing present itself we've got here's the same d message output and so with that that header that we looked at it's not uart because we don't see or it could be uart but we're going to assume that it's probably not it's obviously not spy we don't see like any clock lines or anything like that and the interface is pretty much completely inactive so what could it be it very well could be you know a two wire interface called single wire debug and spoiler alert that's exactly what it is and so what we want to cover with the single wire debugging section is kind of learn what that is learn how to identify it we want to learn how to interface with it via open ocd and also kind of how to once we have the single wire debugging capability if we still don't understand everything about the target cpu learn how to identify what the cpu part number might be via memory reads and writes and so once we have that we're going to try to extract firmware from it and see if we can modify and understand this new firmware and the last thing if we get enough time to go through it is to take a look at dfu mode and how we might interact with that so to kind of jump into this single wire debugging is a debug interface that's specified by the arm debug interface specification or the the adi and some of you may be familiar with that it's a pretty excellent document that walks through how arm specifies these various debug peripherals to work and so what single wire debugging does is it interfaces with something called a debug access port and a lot of these terms kind of get muddled together and i'm hoping through this talk we'll be able to kind of clear up what these different terms mean and what they all do and so by accessing this debug access port access ports or aps are read to and written from in order to actually read and write memory or to interact with whatever internal peripheral you're trying to look at on the device whether that be for you know system level debugging or you know you're just trying to read and write memory or you're trying to interact with some other peripheral like coresight or something like that and so you know we have daps dps which are data ports aps which are access ports and all of these things are kind of connected to one another and the way in which they're connected is defined in the arm debug interface specification so if you just google you know arm adi you'll be able to find the latest version of their interface specification and that's extremely useful for getting a handle on these things at kind of a higher level and so the adi is what you know ultimately provides us access to these kinds of debug ports and so if you're familiar with jtag which kind of links the different tabs together or test access ports single wire debug kind of abstracts those out into different components like we said before we've got the debug port the debug access port and the access port and so these things are defined in the adi and you can interact with them through multiple kind of physical mediums right so single wire debug is just the physical interface that we use to interact with the debug access port which in turn interacts with the debug port and the various access ports and again i know that these these terms kind of get smashed together when you talk about it but we have some diagrams later that i think are going to help clear this up a little bit and so the reason i like to go over this kind of stuff is because when you're reverse engineering something you kind of have to break it down into the fundamental building blocks right because that's all you have we don't know who made this chip we don't know how they interfaced with it we don't know really anything except for that this might be a single wire to bug port and in order to understand how to interface with it from kind of a black box perspective it's important to understand you know how the core pieces work and so starting with that is the dap which is the externally facing peripheral right that's accessed via a single wire debug or jtag or serial jtag like we talked about in the last slide and so that consists of two parts you've got the debug port and the access port the debug port is by default always supposed to be there so the debug port is kind of your your ground truth and so aps or access ports are what define all the different debug features and functionality that one of these chips might have so if you've ever heard of you know coresight or any of the tracing features that a lot of arm chips have those are interacted with through these aps which are communicated with via these physical mediums like single wire to bug or jtag etc and so when you're doing single wire to bug every transaction or every little thing that occurs is going to be sent to either the debug port the dp or an access port in ap and so let's talk about the debug port right so this dp is contains various registers that you use to kind of monitor system state you can use it to get id information about the cpu and this is kind of the piece that you always know is supposed to be there this is what's defined in the spec and so with the dp you can actually read to and write from registers that are used to actually interact with the other aps and so this is all again independent of you know single wire debug or jtag or whatever physical medium you're using but this is kind of the first thing that you start talking to when you go to access something at the kind of hardware level for debugging and so access ports are really where kind of the meat is with hardware debugging that's where we can get access to memory that's where we get access to external peripherals and things like that and so these are accessed through the dp as we mentioned before dp is debug port it's essentially a register that's written to uh the debug port in the adi is like a bank of registers that is written to yeah so internally it may look like a bus but really it's gonna look more like a memory bank it does not quite one of the questions is does it act as a router it doesn't quite act as a router um you write to it exactly what you want to address and it will fetch that for you so it doesn't do it automatically you still have to tell it what you want so in a sense it does route data but as we'll learn later the the packet structure for single wire debug lets you access an ap directly so you don't have to go through the dp and so when you're looking at an access port there's one register that's always used to identify the ap type and you know we're talking about registers we're talking about access ports and you haven't even seen these things yet right these are all very kind of higher level ephemeral things but what you need to imagine them as is just kind of like banks of memory or banks of registers that can be read to or written from in order to access various things that are internal to the cpu and so there's two types of aps that are defined in the adi you've got you know memory aps which are used to access various internal memory buses and so those of you that are familiar with you know vlsi things like that uh are you know kind of understand that there are lots of internal buses that are being used within your cpu and this will let you kind of read and write to those and based on what capabilities the chip provides you can use you know these various memory aps that are presented to interact with these this debug functionality excuse me and then there's the jtag access port which is used for kind of traditional boundary scan or you know standard jtag uses so things for querying gpio pins things like that and so as we said before the the memory access port kind of gives you a window into some kind of abstract memory system or memory bus whether that is something that lets you you know read and write direct from directly from ram or something that's used to kind of interact with the debug unit of the processor and so this is just kind of an overarching category that's used to describe these various access ports that you talk to through you know single wire debug or jtag or whatever your mechanism is but at their core these mem aps are used to interact with the memory of the target cpu and so you know we've got these aps we've got these dps we've got the dap and then we've got swd we've got so many acronyms here it's out of this world but how do we you know learn when we're taking a look at like an unknown let's say we're looking at an unknown port and we can you know read from these dps and these aps we're going to learn how to do that later but how do you know what data is contained within there so each of these these dp's and these aps will point to something called a rom table and this rom table has information about whatever debug component you're talking to and so that is what actually connects to that internal bus that's pointed to by your memory ap and so each of these aps and dps have dedicated registers that point to these rom tables that are used to identify you know what their type is and what they're used for and you know i know this is a lot of we're throwing a lot of acronyms and a lot of definitions out so if anybody has questions toss them in the chat and we'll do our best to get to them so yeah we've got these three acronyms right dap app dp the the dap is kind of the entire overarching debug interface if you think about it the aps can provide access to like various peripherals or memory and internal cpu buses based on how they're designed and how and whether or not they're exposed and the dp is the way that you access these things you know initially it's kind of the standard way it's kind of the first step in the chain to access these various peripherals and buses and so finally what this ultimately ends up looking like is we've got this massive thing right here this is the debug access port right and we can see that it contains the debug port which is the first thing we read to and write to the ap access right which talks to our memory aps and then those are what in this part to us right is kind of done without us needing to know anything and that's why this is all that's why this is all defined this way so is the video blurry for everybody or is it hmm okay i'm getting mixed signals in chat um i'm gonna leave in oh sorry matt uh the the big screens the larger screens seem to be fine uh but if you went to a smaller if you switched to i believe some other the other graphics that you had where the text is really small then that becomes blurry okay uh i believe uh some other discussions and talks they switched uh using the straight zoom uh video feed so uh if you do maybe consider that uh if there's more issues okay i can do that for the for the terminal stuff i'll try to do that and see if we can okay let me go back um but yeah so i'll i'll do what i can to make the terminal video a little less blurry when we when we get to that so sorry about that the so this is kind of the overarching um picture of what these debug ports actually look like so you've got the physical connection which is going to be implemented via you know single wire to bug or jtag or serial jtag whatever that might be that then talks to the dp which is the first layer that we can perform these ap accesses that we then use to kind of get access to memory or you know various debug peripherals and the reason this is all abstracted away is that for you know various cpu designs now all you need to understand is how to access these things right here so the debug port and the memory aps and that's kind of where the beauty of things you know like open ocd and things like that come in because once you understand how to do this on some course you can it might carry over to other processors and so the ap is accessed so we got a question how do we connect to an ap directly you connect to it through either this physical connection which is single wire to bug and then you address you can address the ap through packets that are sent to the debug port and we'll go over that what that package structure looks like here in a moment and so yeah we have this first layer physical connection which is going to be your jtag your single wire to bug your serial jtag what have you and then that talks to you know our entire overarching debug access port the debug port is the first stage of the process that's how we kind of identify the target that's how we get information about it and then we can through that talk to these memory access ports which give us access to you know external memory and internal peripherals and you know one of those things that will give us is the ability to bug the processor and so you know we've got this physical interface single wire to bug this is implemented with two pins which is kind of why it's preferred over jtaggery was developed instead of jtag you've got you know serial clock and then serial data in and out the clock pin obviously is used to determine when you sample data on the single wire to bug line and the uh i o pin is bi-directional so there's like a direction bit in the packet that tells you whether or not you need to wait for a reader right to occur and so when we send these packets to the dp or the dap it can be split up kind of into three parts you've got your header uh the response bit and then data and so the header actually determines the direction of the payload whether or not the data portion is going to the device you're coming from and so here's a blurry picture of what the package structure looks like the the header part contains you know start bit uh a bit whether or not you're accessing an access port or a data port which we just talked about um whether it's a reader a write an address bit parity bit stop bit and a park bit or a turn around bit um and then you'll get an ack from the target and then following that you get the actual data that you care about and so these are two examples of kind of a read and a write transfer the the thing to take away here is to understand that you know we've got pieces of this that are used to access you know the ap versus the dp and yeah the address field is uh two bits and so that's the the data the data field is eventually used to write to other addresses so it gives you more than just a two-bit address space it's basically used to select whether or not you're at which ap you're gonna access if that makes sense and so the packet uh header is pretty small you've got eight bits total start bit the ap and dp bit which basically determines whether an ap is getting accessed or a dp the read and write bit uh one is a zero or one is a read zero's a right the address pit which bit which determines the address of the ap or dp that we're going to talk to um and then you know a parity bit stop bit and a park bit and so this is used the park bit is basically used as kind of a a timer or not a timer really but an indicator of when the host can drive the line um because it's a push-pull line or it's open drain line rather so for example to read you know the id code of a device over single wired to bug would look like some look something like this so first we see our our start bit which is one right we've got the access port or data port bit which is zero so we're talking to the dp we've got read and write uh so remember this is one so it's going to be a read and then the address here just zero and then zero because we're just talking to the data port with this because we're trying to read out the id code and so a data port read at address 0 0 is always supposed to return the id code so that's one of those ground truth things that you can use to figure out whether or not you're talking to something that's single wire to bug similar to how with jtag you can try to clock out the id in order to figure out if the target port's a jtag port or not and so for the parity bit here we have one and then the stop bit and then park which is supposed to be one and then that gets followed up with an ack from the processor um where it's a three bit field and it can be either okay weight or fault that's what they use it for and so this is the processor coming back to us telling us okay and then it responds with the id code so this is the processor firing back the id code after we've asked it to read from the uh we asked it to read from the debug port add address zero and what it returned to us then is the id and so when you're taking a look at you know what you think might be a single wire debug pin or any debug port really you're going to have most likely a vcc pin near there to either grab the logic level or just to let whatever the target hardware is that's talking to it know what the logic levels is and this isn't unlike what you'd see on a ur port and it's unlikely that in typical usage you're going to actually be able to see any activity over these lines because they're designed to be talked to by a host so unless there's something you know on your target pcb that's actively talking to uh your cpu over single wire to bug you're not going to see any activity on these live on these uh on these lines um just looking at the chat real quick these i'm not sure if the slides are going to be shared and i i know the video is getting recorded so i'm assuming that'll get posted at some point uh and so the clock line usually uh utilizes a built-in pull-down the i o line usually is pulled up now that can change on different targets it's not always ground truth it's just kind of what is commonly seen out in the wild and the other thing too is it's really commonly used and seen on you know stm32 mcus which i'm sure everyone in here is fairly familiar with and so when you're talking with single wire debug there's a fair amount of like different hardware interfaces you can use some of them are provided by the oem or the chip manufacturer and there are also you know open source tools that you can use like the ftdi chip you can use the segger j link which you know isn't open source but it's a fairly useful tool there's things like the fly swatter that people can use um and again most of the time when you get a microcontroller you get something from an oem they provide their own hardware solution for it or you know just implement it over usb or something like that or yeah like a blackmagic probe like someone's mentioning um and typically oem tools will also come with their own software suite for talking to these things but you know as a reverse engineer you're not going to have access to all that most of the time there may be cases when you will and that's always great but it's kind of always best to assume you're going to have as little data as possible and so with the raspberry pi we can interact with a single wired debug interface using openocd and telling it that we're actually we're using a single wire interface a single wire debug interface so there were some config files that were shared in the chat if people want to take a look at those uh for if you're ever going to use openocd with a raspberry pi and so you define in the config file the various jpeg or the various single wire to bug pins that are going to be used and so what i'm going to do is connect to the header and for a14 i'm going to connect that to pin 2 of the raspberry pi the gpio and for uh gpio3 we're going to connect that to a13 so i'm going to switch over to the hardware view real quick all right hope everybody can see that all right so we're going to connect up to these first two pins uh this first pin after looking at it with the multimeter and doing a continuity test is ground so we're gonna ground that and then the next two pins 14 and 13. like we said we're going to connect them to two and three on the raspberry pi pin two and pin three and so you know fairly straightforward just three lines um which is nice for us and so we've got that connected to our raspberry pi now i'm gonna switch back over to the terminal and we will figure out the issues with resolution so bear with me here folks so here's our terminal is this too small can people read it i can make it larger okay i'm getting some i'm getting positive uh feedback here so i'm gonna i'm gonna leave it with this um yeah so apologies for that folks uh hopefully this is hopefully this is doable uh and i think this is the max unless i can yeah this is as high as i can go all right so uh we'll take a look at an initial what what the config file looks like so just so you're familiar and i shared this was shared in chat so first thing we're going to do we tell it we tell openocd which presents an interface to us over telnet we're going to tell it what port we want it to uh present to us we're telling it hey use the adapter driver for the raspberry pi that's what this bcm 2835 gpio line is and this is for the raspberry pi 4 this peripheral base address this basically is telling it you know what the base address is for interfacing with these gpios and then we have you know speed coefficients which we're using to calibrate the uh the clock speed for how quickly we're going to interact with this target and then we've got we finally got our gpio numbers here for clock and data end data out now you'll notice right that it's not the header pin number it's the gpio number and this works on uh various revisions of the raspberry pi the only thing that will change will be this base address and they have example config files in openocd for you to use and so we're going to tell it to use you know speed of we're going to go 100 kilohertz and we're saying for the transport select which basically tells it the physical interface that it's going to go over we're saying use a single wire to bug so i'm going to pass it rpi single wired config all right and so the first thing we see you know it's telling us all right for tickle connections port 666 for telnet 0.1337 we're using the bitbang driver for the raspberry pi and then uh so yeah let me see if i can make this video any more clear for you yeah i've got i've got the hd box checked so i'm not sure um so yeah i think this is probably as good as it's going to get as far as video goes folks um so we've got you know this the first error that we get and i chose 100 kilohertz here just to keep things relatively slow um it you could go higher if you want you could go lower i guess if you really wanted to but uh for the raspberry pi this is always a good happy medium i've had some issues with going you know trying to go too high with doing single wire to bug on targets that aren't really you know expecting it or necessarily designed for it so this has always just been kind of the sweet spot um and so it's telling us here right this big the big thing that we're seeing is this thing gdp services needs one or more targets to find and so with that error i'm going to take you back to the powerpoint and so we filled in the gpios to match the target wiring and the there was originally a missing value for transport select that we we added telling it basically hey we're going to be using uh single wire debug as the transport mechanism and so here's what that looks like for those of you that maybe couldn't see it on the terminal and so we're getting this error right that's telling us hey i see that you know you've pro you defined all the parameters of the physical interface perfectly fine but i need to know what target i'm talking to right so that's basically what it's telling us so now we need to define you know adapt that we just talked about so with openocd you can find a new dap with you know swd new dap you give it a name tell it what kind it is and then tell it to enable it and then we create we actually create the dap from the thing that we named here and then now we give it a target and so i'm going under the assumption that this is a cortex-m so you know we get a lot of questions like we know nothing about the cpu right we don't know the architecture we don't know anything what we do know is that presumably we're using a single wire debug interface and uh with that we know that stm32 uses those pretty regularly and so do a lot of other kind of like cots arm chips so just as a start we're going to guess cortex m or we're going to start with you know kind of a more a more common chip and this is you know an assumption uh we'll find out that it's a fairly reasonable one so if we look at the xbox one config which is just that same config file you had before with the dap defined and the other components defined so if the so if the assumption is wrong we got a question if the assumption is wrong it's not going to be able to properly identify the chip so if we chose you know mips or something weird like that it simply just wouldn't work right um and again a lot of this when you're looking at you know an undocumented debug interface with a chip that's covered in epoxy there's a lot of guesswork that goes on and i've obviously streamlined that guesswork because we only have so much time here right so when i was going through this the first time i'm basically uh you're basically you know you're guessing different architectures you're trying to figure out what it is and you you know burn a lot of time doing that so so let's see what happens when we run open ocd with the dap defined all right so right here right we see a lot of the same stuff we saw before but we've also got single wire debug data point idp idr so data port id register and it's spinning back like a proper id and so by reading the info that's defined in the data port it's able to tell us that the cpu has six break points four watch points and it's spinning up you know a gdb server for us and as well as the tickle server in the telnet server so we're now able to query or openocd is rather able to query the dp get the id and get some information back about the chip and so for those of you that couldn't see on the terminal hopefully this shows up um you see we get the dpidr here which is the identifier for the chip and you know those of you that have looked at these before probably immediately know that that's an stm32 series chip um so this was a response that was given to us by the dp when openocd tried to enumerate the target and so now that we have this dap we can go through and initialize it with the init command this will go through and kind of initialize all the registered uh dps and aps that it can find and then once that's done we can print out the info that openocd is able to query so let's take a look at that we're going to go back to the terminal so sudo openocd dash f xbox.config alright so if we go into another terminal we connect to that with telnet so we do init and then we'll type in dap info now this is going to be tough to read so it's a lot of data so hopefully we can follow along here if we scroll up we can see here the it gives us the id register right and then we see it goes through and reads the map so it grabs the base and then starts reading the rom table and so immediately looking at this right we see that one of the peripheral ids and the designer id is for st microelectronics we have the part number which is hex 411 and then when we look at this additional rom table here this for this uh peripheral address openocd is able to go through and query that and read it out and figure out you know okay we can see that it's a cortex m4 which is great coincidentally you know obviously not a guess it took a fair amount of time to figure that out initially but if you were looking at this and you had the wrong architecture identified and you could read through the rom table you would see that this is a cortex m4 and so you would be able to get to this data regardless of what architecture you provided it which is kind of nice and that's how i found it to begin with so you ask openocd to grab you this dap info and here we can see there's a couple of we have a couple of different rom tables that are telling us what the different aps are used for right so we have one for flash patch and break point we've got one for data watch point and trace uh system control space etc and so these are all the different peripherals that we can interact with via swd and so we talked before about like there might be trace modules involved we've got this traceport interface unit and this is where you know reading through things like the coresight specification and stuff like that will come into excuse me will come into play and so now with that out of the way we know that it's an st microelectronics chip we know that much right it's telling us right here it's giving us the part number which is unrecognized this isn't always something you can go off of this hex 411 but the big takeaway here right is that we know it's a cortex m4 because we're seeing that in the dapper table and we know it's an st microelectronics chip so when you start to kind of piece all that together right it's an arm based st chip using single wire to bug good chance it's an stm32 but there's other ways we can figure that out as well and so to walk through that we're gonna go back to the powerpoint okay i'm sorry i'm getting right back i'm getting to these questions now so if the architecture was wrong yeah we would still get the id regardless of the architecture uh debugging and things like that are what would probably not work and yeah the info we were looking at earlier was from the rom table and yeah so hex 411 doesn't exactly mean stm32411 um it's just a manual it's just another id field that's used um sorry i'm trying to get to these as i can here um so yeah we took a look at the dap output and you know we could see things like you know st microelectronics we got a part number we got the architecture as well and so we're gonna move forward you know assuming this is probably an stm32 chip of some sort and so these are extremely popular arm cortex you know microcontrollers they typically have you know the cortex cpu core sram internal flash and the debug interface slash other external peripherals i'm assuming everybody here is fairly familiar with the stm32 it's uh it's an extremely popular chip and so this chip also utilizes the swd interface which is good for us and so these cpus store identification info in various memory regions right and so at this url um which i can i can post in the chat basically they have different regions of memory that you can read from to get cpu id information and so by doing that you can try to now that we can interact with this ap we have the proper architecture figured out we can go through and try to read from these memory regions to figure out what specific chip we might be looking at and so let's take a look at that as you can see there going back and forth between the uh terminal and powerpoint is kind of annoying so i'm going to pull up that stm memory region document real quick and if anybody has any questions just drop them in the chat please all right so this url yeah so the flash um if you're asking when you say locked the flash on these chips can be locked and we'll find out if this one is or not so you can you can lock the flash memory on these so that you can't get to them all right and so if you look at that document there are there's regions that have the generic device id register which is at this address so let me copy and paste it here and so we're going to do mdw which is the memory display word command and we'll just look at four words there all right so we get this for the generic id which is probably going to be the same across uh different different stm32 chips and so yeah the the dap information is always there right unless the single wire debug interface is locked out which it very well could be um so typically it's rare that you would find the entire interface locked out there was a question about whether or not it's possible if the chip is locked like flash locking and debug port locking are independent of one another so you can certainly lock the flash without locking out debug ports and that's pretty that that's commonly seen um hang on so here's the link sorry i posted it in a dm not in the chat my bad everybody there you go okay yeah so we read from this first this first region which uh is kind of the generic device id register and then this next region is defined for stm32f0s and stm32f3s so we're gonna try to read a couple of bytes from that and see if we get anything all right so we have nothing there okay so we'll move down the list to the next one which is one fff f7e8 for stm32f1 and we get nothing for that as well so one ff f7a10 okay so this is for stm32f2s and stm32f4s and mike i knew that address because they're labeled in that header file that i just posted a link to so those are commonly used addresses for identifying various types of stm32 chips all right cool so we got you know we saw that we can read we actually have something at this address so between that and what we saw in the rom table it's a fairly safe bet that we're working with an stm32 f2 series so now i'm going to go back to the powerpoint and so you'll see here i wanted to include this example as well you'll get an error if it fails to read memory if you can't actually read memory from that particular address that you're trying to read from so someone had asked what if it's not memory mapped this is exactly what you're going to get or what you're going to see so of all these only one of them worked and it was the one that was specified for the f2 and f4 series the stm32f2 stm32f4 so yeah this confirms to us that's an stm32f2 or f4 series and so luckily for us the good folks at openocd have a configuration file for that specific cpu um yeah and it could also it could also be an l0 that's correct so someone asked here f2 f4 or l0 yeah it could be any one of those so if we look in openocd at the config files we have one for the stm32 f2x chip and so we can include that file with our original config that we wrote in order to get some more information about the chips let's do that now take you back to the terminal so and if you're looking for these if you're looking for these config files after you've installed openocd they're in user local share openocd all right so again as we saw before the rpi-swd config is kind of a generic single-wire debug adapter config you can use and i believe that there are that openocd actually comes with those pre-installed for the pi um i just wanted to use i just wanted to you to write one to give you an example of you know how they're written and what the various fields mean all right so we provide the target stm32f2 cfg all right cool so the cpu gets created now we have a gdp stub that's available but more importantly all the information in that file gives us access to things like the flash commands and it defines the various flash banks and the various debug peripherals so we can actually get in there and start interacting with the the target chip so if we go back now if we do flash banks right we can see that we have two flashbangs and these are defined in that uh that config file target stm32 f2x config dot config so we've got the flash memory and then we've got the one time programmable memory here and so that can be dumped to a file so for those of you that are uh following along we can just do flash read bank bank id we'll just give it zero and then file name we'll call it bank zero dot bin all right and so again this if the the flash in these chips can be configured to be uh re-locked and right locked so luckily for us so far we can still read from it and we'll find out later that it's fair unlocking these is uh doable just via a command that open ocd provides to unlock the flash which is nice it could have been locked in the otp and then we would have had to resort to you would have to resort to something like uh glitching to to bypass that so for these the uh the flash banks are unlocked which make it kind of a nice target for learning this kind of stuff so now if we go back to the powerpoint right we saw that we had you know two flashbangs that are available for those of you that are looking at it and you know there's additional flash commands which we'll take a look at uh later on and you can dump that out with flash read underscore bank and then give it the bank id and the file name that you want to use and so this is what flash list would give you and we saw this this is reading the bank and yeah so luckily for us uh which again is kind of why this makes uh this controller makes for a nice target for learning these kinds of things is uh the flash banks here are unlocked so we're able to read and write to them which is nice and so we can read bank one and bank zero if we want to take if you want to take a look at that you can do you could look at it in a hex editor you could do you know toss it into guidro whatever you feel like doing so at this point we've read you know bank zero and bank one bank one being the otp memory which is where some of that lockout information would be stored and so now that we have these two these two flash banks we can you can take a look at it with something like bin walk you could do hex dump you could just run strings on it um because you know right now this is just a flat firmware image the the format is not necessarily known but we'll find out later that it is actually defined in an abi for this chip but you know the first step that you want to do with something like this would be to run you know bin walk or hex dump strings what have you so i'll hop back to the terminal real quick just take a look at that and yeah so someone asked in the chat what is otp memory it's a one-time programmable so if we just run classic bin walk on it see what ben walk says probably not going to get much yeah because this is just a flat memory image if we run strings on it x0 and we'll pipe that up okay we're not seeing much this is all kind of garbage but we are seeing you know xbox input gamepad pdp gamepad etc and so you know it's it's always good to kind of do stuff like this to make sure that you're actually dumping stuff data that makes sense um and that you're you know not getting corrupted data or anything like that so another thing that we can infer right if we're seeing plain text strings like this in the firmware image it's likely not compressed it's probably not encrypted in any way and you could use bin walk dash e to figure that out and so we go down and we see you know some more of this manufacturer data that we saw when we enumerated the device and so yeah it looks like we've got a relatively complete image of the flash by just using the flash commands and open ocd just kind of nice let's go back to the powerpoint and so yeah this you know these uh strings here let us know that one the data is probably not encrypted and or compressed in any way and these also would be you know kind of good candidates for if we wanted to try to rewrite or patch the firmware this would be something we could change to kind of get a visible result but as as has been mentioned in the chat stm32 chips can protect and lock these flashbangs and you can also prevent readouts as well um and also when you are writing to these flash chips they have to be erased first it's kind of like if you've ever read to or written from you know a spy flash or an uh an i2c flash um but you know openocd has support for halting the cpu obviously and then you can try to unlock the flashbang so that it can be read to or written from and so if you're you know if you're following along at home you can now you know you can try to patch it and see if there's any changes you might want to make um but to flash your modified image to the stm32 uh first we would want to halt it unlock it and then there's the right bank command which does the erasing and writing for you and then reset it and so we can take some time now and try to do that and see if we can change something that we can actually visibly see so i'm gonna switch back yeah so uh regions of the flash could definitely be encrypted uh they could definitely be compressed what have you if we look at this in a hex editor so let me go back to the terminal if we take a look at this in a hex editor we're seeing you can see a lot of and i know this is probably hard for cert for folks to read um the there are like definitely some patterns in this as you take a look at it so throughout it doesn't look like you know it's compressed there's not a whole lot there's not super high entropy here you see we have like two almost identical strings of bytes these are all probably you know similar instructions that are being run um so yeah we're not seeing you know high amounts of entropy we're seeing plain text strings in kind of the middle of the memory dump we're not seeing it you know at the header or the footer so yeah this would you know lead one to believe that it is probably unencrypted and you know i've loaded this up in ghidra and patched it and modified it and i can tell you that it's not encrypted in any way so if we want to you know find something that we can modify and change we've got these strings over here that we saw get you know presented when the device was enumerated and so let's go ahead and change this to give me one second always make backups yeah the uh the terminal is browser based um use this for a training platform as well and it just makes life typically makes life a little easier if you're not uh streaming to a bunch of people so go back to where we saw those strings and we'll just patch those to be something different and uh those of you that have read my blog post before probably pretty familiar with how a lot of this works so so let's do that so we're going to modify one of these descriptor strings to say you know hack their emoticon firmware patches etc so save the changes so now let's halt the processor i'll do stm32f2x unlock bank zero build unlock device do it again and it works so this this is another kind of quirk that you might see when you're doing this with openocd it does typically fail the first time and i'm not sure exactly why that is if there's any open ocd experts in the chat that might be able to explain that that would be pretty cool but i have noticed that you do have to issue the command twice but so now that that's done we can do flash right bank and what we call mod.bin oh i forgot the bank id so bank zero month.n oh no error writing to flash why is that failed to get read pointer all right so we halt unlocked oh i said read bank not right bank gee all right okay no yeah so uh enrico this firmware image is uh very friendly for modifications there's not really any checks or anything on it which is kind of why it makes for a good target for a lot of the stuff and makes it easy for people to hack on yeah there's there's no check summing there's no kind of signature or anything i mean it turns out right the mod the you know potential threat model for something like this is not super advanced um they're not really expecting anybody to go digging into it i don't think uh as it's a pretty cheap controller but in addition to that there's there's also another debug interface that we're going to take a look at later that they that they left in which is pretty cool so we've reflashed our firmware image uh that we just kind of like patched those strings on uh so now let's just exit here so we've reflashed let's kill our see anything we do d message w and so let's re-enumerate our controller and see what shows up okay all right so the product string is all jacked up and so i'm pretty sure that's because we're using a different image that i wrote that i actually wrote a different patch for which is why that's so messed up so let's see if we can get around that and fix that all right go back to the slides okay okay yeah so we were able to reflash and patch it and so this actually we weren't able to see the changes that we made because this actually has a different image that i've that i've patched to do some other stuff so i'm trying to see if i can find the stock image to reflash it but the the main takeaway here is that you can patch this with whatever you want and it doesn't really do any checks or anything on it and so for this example here i had patched it you know with wrong body's artisanal patches and i had managed to also spell artisanal wrong so with that you know you can unlock the flashbang you can modify it and then you can re-flash it all using you know open ocd and single wire debug which is pretty nice and so you know we can modify the flash content we have full control over what it executes at this point we can we could try you know if you wanted to try to do something malicious maybe overwrite some of those strings with format strings see if anything happens um you have you know full debug capabilities over this so you can single step through instructions you can you know halt it reset it you know grab the register state anything you would want to do uh with you know gdb or what have you can now do uh do thanks to openocd and single wire debugging so let's take a look actually at how to do that with openocd and gdb so we're gonna go back to the terminal yeah totally you could so cisco just asked you know you could add a bash bunny app of some sort yeah you could pretty much do you know whatever you want you have full control over the flash you have full control over the target and uh that's kind of where the magic of hardware debugging play and yeah speed run for sure so that was actually the reason i came i tried to look at this before is i was so tired of getting my butt kicked in marvel vs capcom and i wanted to try to write some macros to see if i could get it to work and um i ended up writing something but even that wasn't enough to help me not be terrible with the game so that's just you know that's just on me so learned some cool stuff along the way uh and i hope that was uh you know useful for you folks as well um so uh what were we just we were just talking about uh connecting it up to gdb so let's take a look at how to do that in the terminal so again uh gdb gives us a gdp stub when we spawn it so do this again there we go and then over here we'll just type in gdb and so one thing to note actually uh we're running on a raspberry pi which is arm and so typically if you were trying to run you know gdb targeting a remote arm box you would need to make sure your gdb was compiled with arm support or with whatever you know architecture you're targeting support the nice thing about running all this from the pi is that for arm targets obviously that's supported out of the box so we'll do set architecture arm we'll do target remote local localhost and the gdb port as you can see is on three three three three so we can see right here the gdp port is on three three three three so and there we go so it's telling us you know we're executing at eight zero our pc is eight zero zero two f six six we can do info reg sorry if i could type info reg and then we'll get all the register information and then if we wanted to we can single step so we're stepping through instructions if we want to disassemble we can do x10i at program counter and so here's the instruction that's getting read so you know and you could use a graphical debugger basically if you wanted to right because openocd gives you a gdp stub with a lot which lots of other tools are designed to interact with um we're using the command line version here because it's fairly easy to get up and running and to use and to kind of demonstrate the capability so yeah with this with single wire debug and from the raspberry pi now we have you know complete control over this controller so you could turn it into really whatever you want um as long as you took the time to you know either patch the firmware or write your own firmware um but yeah so thanks to this hardware debugging port we can now do sort of whatever we want so if you wanted to set breakpoints so let's take a look at where we are let's look at how many instructions are in front of us so we're doing x which is the examine command in gdb for those of you that don't know and we're telling it to examine 10 uh you give it a quantity first and then you give it a format of what you want to examine and we are telling it uh instructions so we're saying hey show me 10 instructions at pc which is the program counter so okay cool here is you know the current instruction that we're executing um you know we saw before that the processor had a certain amount of break points and watch points so if we want to set a breakpoint we can now do this so we can just highlight our address and so for those of you that have done you know exploit development or reverse engineering what have you like having this level of debugging is extremely useful right because you have full control over the system you can you know set break points set memory watch points whatever you want so if we do break star and then our address it's telling us we have a break point of this and so now if we do continue to ask it to continue execution bam we hit our break point and so again just to kind of illustrate that now you've got full control over this uh full control over this controller that sounded kind of weird but so yeah via single wire debug openocd you now have full control over this thing and you can reflash it to run whatever you want you could you know try to write macros try to patch it etc so that's pretty that's a pretty interesting thing and that's kind of the power of hardware debugging and we were kind of going from you know a zero we were at kind of a zero knowledge point when we started right the cpu is covered in epoxy all we had was the uh the debug port which you know luckily for us was somewhat labeled and again as people pointed out we are lucky that it the flash was unlocked uh it totally could have been locked and that would have completely that would have stopped us pretty much dead in our tracks as far as only using openocd and the raspberry pi we would have had to resort to something like glitching or some kind of timing attack or something to bypass that setting when trying to access the flash uh so yeah gdp these are all gdp commands that i'm running there's some questions in chat about that uh gd also has a disassembler baked into it so you can tell it like hey i need you i want you to disassemble this address so what is running on the controller is is a bare metal firmware image it's not it's not an os it's not a little rtos or anything like that um so yeah these are all gdb commands that are that are being run right now so c is continue and so we're still hitting this break point um yeah so now we have you know full full control over the system we can single step through instructions no problem we can examine memory we can examine instructions so yeah at this point we have full control over the controller and with that i'm going to go back to the powerpoint the pi is running the gdb server that's a great question so someone is asking does the game controller have a gdp server running on it no what the game controller has right is that that interface that single wire debug interface that we are talking to and that's where the magic of openocd comes in because openocd knows how to talk to all the internal components all those internal aps and spin up the same capabilities that a gdb server would expect so openocd spins up the gdb server handles all the memory reads and writes for you and does all that behind the scenes so we have to thank the the developers of openocd for setting all that up for us which is really cool so you know we've we talked about this we can we can patch the firmware we can do whatever we can rewrite the flash what have you no big deal so you know we can single step debug which is also great and we already went through this we talked about looking at it with gdb we set a break point et cetera i feel like it's easier to show in the terminal versus uh powerpoint so someone asked is there an advantage to using openocd with the pi versus j-link um you can use you can use either uh i wanted to focus on the pi because i think it's more accessible and it's you know as far as the end result is is a lot of the times it's going to be the same there are platforms that j-link might have better support for are baked in support using their software tooling uh i like to try to use something that's as configurable as possible if that makes sense like the raspberry pi in case you run into like some kind of bespoke feature or some weird quirk that you don't know how to deal with so i like using the pi for this but there's a number of different interfaces you could use for this and they all kind of have their own pros and cons so uh i mentioned before that i bricked one of these on accident and so what i had done was i overwrote the flash with the wrong file so i actually i accidentally overwrote the flash with a chunk of a markdown file because i just fat fingered some keys and so what that did was it caused the stm32 to obviously not enumerate when it got powered up right so i i reflashed it and i plugged it in and nothing showed up so because it wasn't getting enumerated it obviously didn't show up as a usb device it didn't even show the single wire debug ports weren't even active because they weren't properly configured by the the bootloader so like nothing had run and things were not working and so you know that happens uh sometimes you fat finger something sometimes you goof stuff up but as i was um i'll say it angrily like trying to plug this thing back in and figure out like how do i get this stupid thing to work i found out that this has what's called like a dfu mode that's built into the boot realm for this exact scenario for when a big dummy like me goes in and flashes the wrong firmware to it and uh this was something i found just a few days ago so i was excited to be able to toss it in here which is kind of cool so if you have one of these controllers at home and you hold these three buttons in while you plug it in you'll see that something different pops up so i'm gonna i'm gonna load up d message in the terminal window for those of you that can see it and we're gonna take a look at what that does all right so i'm sliding over here to get to my hardware and so let me flip this around so it's uh these three buttons so if you hold these down so spork i'll show you we'll go to the hardware view real quick it's these these three buttons so here here and here so if you hold these three down and we'll go back to the terminal so we're gonna hold these three down unplug the controller we see a usb disconnect great and now plug it in again we've got a totally different usb device we see stm32 boot loader manufacturer st microelectronics and so this was kind of a godsend because i was concerned that i had bricked this and i used this a lot for courses and training and i was you know somewhat worried that if it's this easy to brick it it's extremely easy for other folks to break it remotely but this uh dfu mode can be used to reflash the device and this is what you'll see a lot of times you know commercially available like development boards will present this interface and dfu is a device firmware upgrade so we'll go back to the powerpoint yeah so dfu device firmware upgrade this presents you know a custom usb device that we can interact with over usb to get access to the flash and so here we go like we press these three buttons and then we see this new stm32 device show up which is very nice someone says the combos up up down down left right left right b apa yeah not quite um so yeah this was kind of a neat little easter egg that they left in there for us and again like this this controller is not built with a ton of protections you know in mind right so this is not something you see on a ton of devices it's not something that's super commonly found in the wild but it's it's a good thing to be aware of right so you can think of this similar to how like you know certain android phones or most android phones you hold the volume down it goes into boot loader mode right that's used for recovery that's used for you know all other kinds of like reflashing modes or whatever and this is kind of something similar and so brandon says yeah except for the auth chip that's a hundred percent true the these do have an internal uh authentication algorithm that has to go back and forth with the xbox one um i looked at that pretty heavily with the 360. i haven't looked at it with the xbox one so i'm not quite sure how it's implemented but basically what you would do on the 360 is you would capture that authentication you would capture the using something like usb proxy you could capture the authentication request and then after that redirect the usb traffic to essentially like another code path so instead of reading from the controller you would have like a man in the middle kind of thing that would uh basically perform the off and then you would hot swap over to your custom controller that would send the necessary hid stuff and that's what most of the commercial stuff i actually will do that's why you have to plug a real controller into it a lot of the commercial older commercial stuff because you have to pay money for this like little ic that you soldered your board and the original xbox would send you like a nonce basically you would send that to the ic you would get a challenge back ship that back to the xbox and that's how you would keep it from uh you know keep people from making third-party knock-off controllers and yeah this controller is a third-party controller it's not an official xbox controller i haven't looked at the official ones mainly because they're they're kind of pricey and i don't feel like breaking something that costs you know that much money but these are a little more expendable so again now we have this device in dfu mode so with that you can use the dfu util to kind of interact with these and that's an open source tool that you can use to interact with these devices while they're in dfu mode and so by passing it the dash l argument you can see uh the different dfu essentially like peripherals that are presented so we can go back to the terminal and do that real quick so dfu until all right so what did i do oh sorry folks give me one second i thought i had already built this apparently i had not see how well this works building something live i don't understand what could go wrong here uh matt there's a link to the um the controller on the hackaday io page and uh i can i can post that as well just give me one second so yeah as we watch this go by i'm happy to answer any questions people have um so is there otp bootloader reading the pins and jumping to the wrong boot loader or did they hook the buttons up to the boot pins great question andy i don't know and it's kind of hard to tell because the chip is covered in epoxy uh so i can't tell what pins they're connected to i only know the outcome when you hold those three buttons uh i wish we had the pin out right if we had the pin out and we had the part number we probably wouldn't be here doing this um so i have to assume the otp bootloader is jumping to some other internal uh read-only memory that's usable all right so that seems good let's build this now please don't all right looks like we're good so now if we do dfu util dash l can't open the device we have to run it as a super user all right cool so now we're seeing these these uh these interfaces that are presented and so these are the different features that if you've ever written code for an stm32 there are options you know option bytes basically to configure various things about the processor there's you know feature bytes that you can read and write from and then the one-time programmable memory that we talked about before so uh we also have you know access to the internal flash which is super useful because in my case when i had reflashed this controller with a markdown file and it didn't run it was nice to be able to access the flash via this dfu utility so if you want to read that out you can do it with the following command so we can do let me go back here dfu util and then so first of all we'll give it the alternative number here so we're going to say if we wanted to read the internal flash we do dash a zero dash s and then give it the range so we see here that it starts at hex eight zero zero zero zero zero zero which makes sense right that was about the address range that we saw in uh the gdb prompt that we were in so let's paste that and then the flash size we know from before but you can also see here that they've got um the calculation here so this four times zero one six kg essentially translates to zero x four one two three four and then we're gonna tell it to upload which might seem counterintuitive upload meaning uh upload the code back from you know the device and let's just call this dfutest.bin very creative with our names here so we'll do that see we're uploading the internal flash now if we look at the let's let's take a look at the strings of the internal flash just to verify we're actually getting what we wrote to it before so remember before we change that string to say you know hackaday u remotocon what have you so let's take a look at this dfu test step in like that less and let's go keep scrolling down i'm sure this is horrific for those of you that are trying to read this and so let's see let's go back to this so this is the hex editor in the terminal let's go back and see if our changes are still in here assuming we didn't mess anything up oh interesting so something got something got messed up huh so it looks like it didn't actually what did we do wrong all right let's take a look at this so yeah we read this app but what we read out is actually different than what we had written to before i may have oh crap i sorry folks i swapped controllers on you in between i grab i have three of them here on my desk and i grabbed the wrong one so we we read the flash out over dfu till someone was asking for the arguments and the arguments are right here so the arguments are dash a for the essentially like the address or the um the interface number so in the dash l output you could see that there were interface numbers that were appended to things so we have zero whoops we have zero one two and three and so dash a is for zero one two and three and then s is the start address and then the size upload saying hey we want to uh we want you to upload code us and then dfu flash.bim and so we can use this this dfu utility to read out the various flashbangs the alt setting which is how we tell it what bank we want the address range so we give it the range that we care about and then we tell it hey we want to upload the information back to us and so now we can you know write the original image back we can also erase and unprotect the flash so i'm going to do that now in the terminal if anybody has any other questions definitely feel free yeah these controllers someone's mentioning in the chat these controllers are super cheap used um they're like typically less than ten dollars so i'm typing in that command now to change that okay and just so you can see what that looks like so we're telling it hey we want to force unprotect the flash region for this interface and it tells us right here that everything's good and so when it disconnects though that's not necessarily a problem but we've unprotected the flash it disconnects and now it's showing up as the the original device again let me see if i have a stock firmware image that we can flash to it really quick one moment and yeah any questions definitely toss them in the chat and we'll we'll get to them uh some people are asking um yeah so you'll you do you will notice on the silk screen if you have one of these it does say single wire to bug backwards so if you hold it up into a mirror you know kind of like candyman style and say its name three times you can also get access to the single wire to bug port that way let's give me one moment here i'm looking to see if i have a firmware image that we can reflash to it and yeah please by all means ask ask away as far as questions go it is so jack is asking um is it internal flash or spy it's internal flash uh so now right if we want to upload a new image the first thing we have to do is boot it back into dfu mode so we've unlocked that flashbang so let's boot it back into dfu mode okay we can see that there stm32 bootloader and let's go back here so now let's take our let's take our image that we just read let's copy that to rank it up in and let's change let's see if we can change the serial number so we can see here the serial number is zero zero zero fd7 c95 so let's see if we can find this okay not found great uh probably not true this is not the best text editor i just use it uh in the terminal so that other folks can see what's going on so let's see what we can find if we could find that and change it see if we can re-upload that okay yeah so this data is all kinds of corrupted here which is interesting i'm not sure what i was thinking when i flashed this one um i also may have another stock one somewhere um so let me see give me one second let me see if i have another another stock one that we can grab since we've got a little time all right folks we're in luck we've got a we've got a stock stock controller so so running uh running a stock tune um all right so let's go ahead i'm going to connect that one up so yeah you guys are at the hardware view uh jaren is asking how did you get started with all this do you mean reversing in general or with this controller because i had explained before the controller stuff started because i'm terrible at fighting games and i wanted to try to stand a chance against my friends and obviously that didn't work very well yeah so i can totally just grab the the flashover dfu and i'm going to do that with this this new stock controller that doesn't have any kind of modifications to the image so that we can actually uh see some changes when they happen so plug this guy in let's go into let's go into dfu mode hold down the buttons and another interesting thing if you have this controller you can um when you hold those buttons it makes the the motors rumble i don't know if you guys could see that on the camera but uh it makes the motor rumble which is kind of an interesting feature it actually it almost sort of scared me when it happened the first time like what on earth is this uh so yeah we plugged it in and again here it's showing up so stm32 bootloader so let's upload it and we'll do stock firmware cool so we've now read the enter the internal flash and so one thing that you'll notice if any of you do decide to take a look at this and to modify it um the null termination on a lot of these strings like isn't really properly implemented so you have to be careful when you're just patching this hex file um so that you don't uh overrun anything so we know that this shows up so let's try let's try we let's try that again so we're going to say hello hackaday emoticon remo take on get it together matt and yeah so then it's going to say testing controller firmware patches and then we'll just do all right so here's our let me just i didn't realize you folks were looking at the hardware i apologize so here is uh let me move myself out of the way so here's our little patch that we're going to add and so now let's see if we can flash that apologies that the camera is kind of all over the place all right yes save the changes so now we're gonna unlock the flash um and we're gonna need to it'll reset itself so i'm gonna hold the buttons when i run this because it's gonna unlock the flashbangs and then do like a soft reset so we'll do this okay and so let's just double check d message make sure it's showing up it is it's showing up as our bootloader device and so now to reflash a new image we'll do dash so defuse address the same eight and then six zeros one two three four five six yeah the rumble was actually a little jarring um i wasn't sure if i if the first time it happened i was just squeezing the controller too hard because i was frustrated but uh yeah the rumble can be very jarring so we'll do uh dash d for the target file we want to do and then mod.bin so we've uh we pulled the stock image we patched it and then we are now gonna we unlocked the flash it reset itself we put it back into bootloader mode and now we're gonna push this modified flash image and yeah joseph is saying they probably stored it somewhere i think he's right um because that same serial number i think does show up in one of the other like otp blobs if i recall correctly so with a dash capital d now let's see if we can re-flash with our mod.bin file let's see what happens here okay so first you're seeing that it's erasing so we talked about that before we have to erase first and then we have to write to it so let this get moving yeah there are there are a lot of mats in the chat huh um yeah so in general um re for me i kind of got started just patching games in college like older game boy games and things like that i had a lot of friends that were playing uh emulated versions of pokemon and i didn't have the time to keep up so i was trying to like patch save files so that i didn't have to play as much um most of my re uh initial steps in aria were me just being lazy with games if i'm being completely honest but it made it interesting and it made it more fun um so that's why i like when i teach this stuff i try to do it through like game consoles and things like that or you know console peripherals smaller game cabinets etc so all right so we we've reflashed it and now let's uh let's try to reenumerate and see if our changes actually took place so i'm unplugging the controller now plug it back in so we see usb device what do we got hey so there we go here's our hello hackaday remotocon testing controller firmware patches so uh we can now we can reflash this via two ways right we can do it via single wire to bug and open ocd or we can do it via dfu util and the the nice thing about dfu u2 i think is andy's pointing out here is if you know how to make it enter this mode you don't have to solder anything to it so those of you that have this at home you don't have to crack the controller open and solder to those pins because unfortunately with those pins soldered to you can't close it back up so now that you have this little bit of knowledge you can go through and just hold those buttons when you plug it in and uh then you can use dfu util to read and write and re-flash the firmware and so with that i'm going to jump back to the slides uh spork is asking how we learned that it was dfu enabled that was honestly completely by accident i was holding buttons down while i plugged it in and uh i noticed that it rumbled when i plugged it in um and so it's not an uncommon feature as other people are saying in chat to have certain gpio lines tied to certain boot modes uh it's super common in the automotive space it's common in i mean most microcontrollers right they can they can boot up into other boot loader modes in order to you know re-flash or read firmware so oh it wasn't the rumble that told me it was dfu uh someone said it was the fact that it presented itself as uh let me go back we're in the terminal now so it presents itself as a different device and that's how it was uh understood that it was dfu yeah it wasn't uh i'm not like a rumble whisperer i didn't know like oh it rumbled this many times it's this is obviously a dfu rumble no it was a it showed up because what had happened was because i had overwritten the device with a bad firmware image nothing showed up when i plugged it in so i'm you know frantically sitting in d message plugging and replugging and then i had access i was accidentally holding those buttons down when i plugged it in and the device showed up um so that was a fun fun evening for sure but yeah as someone mentioned uh yeah hard work to avoid playing yeah that's that's pretty accurate actually working hard to avoid play so yes let's go back we'll go back to these slides now and so yeah people ask you we can pull the firmware over dfu you can reflash it we can do uh basically everything that we can do over um single wire to bug except for obviously the image isn't running so you can't single step through the firmware when it's in dfu mode dfu mode is used strictly for reflashing and and you know it's frankly probably a little safer because you're not running an active firmware image while you're trying to reflash things if maybe if you don't properly halt and try to re-flash it which could have been what happened before when we saw our issues um this stuff never work you know when you're approaching this as a reverse engineer it's important to remember this stuff doesn't always just work out of the box like it's supposed to right you're gonna run into setbacks you're gonna you're gonna have issues and that's why it's kind of important to understand what these things look like at an extremely low level and so if you took the geidra course that we put together we kind of architected it such that you know you had such a the goal was to give you like a strong understanding of the fundamentals and it's really no different here right so by understanding the protocols and like what to look for and things like that you you're in a better position than just kind of blindly you know trying to fire away and get stuff to work because nine times out of ten the tools are obviously awesome but they're not designed necessarily specifically for reverse engineering right they kind of assume you know a lot about your target they assume you have the right hardware interface and a lot of times that's just not the case so as a reverse engineer you kind of have to make do with what you have and what we have are the core fundamentals of the protocol that we've talked about today and i hope that makes sense if not i'm happy to elaborate i hope that's not too preachy but so yeah dfu mode i can post the command line for this on the course page if people are interested in that for those of you that have the controller at home and want to take a look at it without soldering and desoldering and so yeah this was interesting in dfu mode single wire debug doesn't work so that's why when i had originally bricked mine um the this was super useful so there may be ways to get it to work in uh single wire to bug i was unable to get single wire debug working in dfu mode and i wasn't sure if maybe the port was just disabled so that was just an interesting thing but basically regardless of what state you put this device in unless you somehow overwrite that core bootloader which i wouldn't recommend you do uh and that may even be otp right there's a good chance that that internal bootloader isn't something you can access anyway um so but between dfu and single wire debugging we have you know complete control of this uh of this controller so um you know quick recap the controller has two mechanisms through which we can upload and download firmware single wire debugging and device firmware upgrade dfu mode and as was pointed out there are no protections on the flash banks if there were that would have prevented us from reading or writing and so luckily for us that was not the case and the boot rom for this particular stm32 has handlers that are capable of jumping into dfu mode which we found that you could enter by pressing those three buttons on the controller so uh just a quick quiz uh if people want to shout these out and chat you know how many lines do you need to implement yep two people got it yeah you need two lines to implement single wired a um what determines the direction of data flow in the packet and i know it's been a while since we looked at the packet um but so let's yep header bit perfect and so uh and this question is probably a little vague but where does single wire debugging fit in the grand scheme of the dap that we talked about right so how does single wire debugging fit in that that equation that we had with we had you know the dap the dp the ap right so single wire debugging is the hardware interface that's used to talk to these things perfect and so how many types of aps are specified in the uh the arm debug specification oh man you guys are paying attention that's awesome uh yeah so there's two mem ap and jtag ap uh and someone asked the flash unlock features are they available in jlink or openocd they are available in both i believe they both have mechanisms for uh um unlocking flashbangs does it require is it common for dfu buttons to require those and only those um that's a good question we can find out let me uh i'll hold down more buttons than those three and we'll see if it still boots into dfu mode i have a feeling it will um but could be wrong and andy's asking openocd can use the j-link hardware yes it can um the thing about it is with j link and openocd from what i understand and things may be different um it has a i don't want to say rudimentary because that sounds condescending uh it it does openocd's driver for the j-link adapter i don't think is able to control it in a super uh well-defined or like in a super granular way so they're able to you're obviously able to do single wire debug and jtag and things like that but i think the segger j-link software is capable of doing more with that hardware than open ocd and that was a long answer to a fairly short question but yes you can use it um but some of the more advanced features that you might see in the segger software i don't know if those immediately translate over to open ocd or not and i think that's because the driver for that device is closed source right so spork is saying uh it has its own driver and commands exactly that's why the way openocd interfaces with it is fairly bare bones so you don't get a lot of those additional features so i'm going to hold additional buttons on the controller and unplug and replug so i'm holding the three buttons and i'm gonna hold geez i'm gonna hold down a as well and let's see in the d message window what happens okay we got a usb device disconnect as expected yep still shows up with uh holding additional buttons so it looks like it only looks for these three uh which is interesting actually let me see if it only needs one um i i always assumed it was just three oh interesting yeah okay yeah so it looks like it's just those three uh so it only works with the three but so uh with that being said we are like right at seven o'clock and we just got through a single wire debug so i don't think we're going to have time to get through jtag so with these last few minutes we'll wrap up and then take take any questions and talk with folks so um you know single wire debug is a physical interface that's used to act interact with the hardware level debugger it's commonly implemented on you know stm32 and other arm based chips again it's the arm debug interface specification so it makes sense you can see it on a lot of arm chips and that specification is what defines all of the various hardware components that are utilized by swd so the different aps the dps all those acronyms that we talked about before and so using single wire debug we can take full control over this target system but it's important to remember that there are security mechanisms that can be put in place to restrict the level of access we have over single wire debug and it's extremely common in targets to see the flash banks uh be locked so essentially they'll get locked to where they're uh like write only so you have to erase it and then you can write to it but you can't read from it and people do that to protect ip things like that all right so any questions oh four more hours yeah i can't i can't uh i can't quite do four more hours folks i'd love to but i really uh i really can't but i i really hope this was helpful and i'm sorry that there were some issues with the terminal um i hope that you know hopefully in the future i can figure out a better way to do that i my my monitors are pretty high resolution so that's that's that's on me so i apologize for that i'll try to make that better for the last time um so yeah i hope that uh i hope you guys had fun and i hope you learned something and yeah i'll hang out uh for any questions folks have happily um uh well matthew i think we're we're we're good until 4 50 or 7 15 or 15 more minutes uh so you can definitely free up i've got some time so okay yeah we can jump we can start to do the jtag stuff um for sure so we can yeah we probably won't get into a lot of the tooling and stuff because that takes a fair amount of time but we can at least go over it um if there's no other uh questions doesn't look like there is yeah um so for more you know material and stuff check out the the github i o page for this class uh some people were asking about the geidra course that we put on through hackadayu there's a github bio page for that as well um and uh yeah we can all drop some links to that in the chat before it ends i'll do that right now before i forget um yeah in case you aren't completely tired of listening to me talk here's hours more of it all right so here's the here's the guidry oh i sent that to thomas again i don't know why i keep doing that i'm sorry thomas i don't know why it keeps defaulting to you uh yeah so here's the guidera course and here's uh my other page with various embedded re musings feel free to enjoy that um so yeah we can jump in we can with the time we have left we can jump into jtech from kind of a high level so let's do that all right so this is ssd we're not really worried about this we're just going to burn through this really quick this is we don't care about any of this all right so um we're going to spend the next couple of minutes just talking about how jtag works what it is what it isn't uh things like that because it's an ext much like the debug access port it's an extremely overloaded term as you'll come to find um so what is jtag it's an ieee spec joint test action group similar to how single-wire debug is a physical specification for interacting with a hardware peripheral jtag behaves the same way it was originally designed to grab i o levels for different chips and to grab you know pin states over a small amount of pins so instead of having to you know physically test each pin you could clock signals through this interface and figure out what the i o state was of every external gpio pin where this gets confusing is that jtag both defines the the protocol layer specification and the test access port that's used for debugging so think of that as like the dap that we talked about before that's defined in uh the jtag specification as the tap and so it's this is where like it can get really confusing and it's extremely overloaded term you hear people talking about like a j tagged xbox and stuff like that it's like it's not a verb it's not you know it's uh it can be you know very confusing uh when you first jump into it yeah someone here says jtag is not jtag that's a great way of putting it so at a minimum it's made up of these four pins you've got clock test mode select tdi tdo data and data out there's other additional pins that you can add uh like real time clock and tap reset for controlling the state machine um but that is you know in a nutshell what the physical interface looks like it's typically at least four pins you'll often see a system reset pin connected to this as well and you'll see you know power and ground typically too so clock is used to control you know when data sampled how data is sampled tms is used to control where we are going in the jtag state machine so there's a state machine that the jtag specification defines that controls what you're writing to what you're reading from and we'll show that here in a moment tdi is used to sample data and write data into the register tdo is used to read data out and so a lot of times when you you see people talk about jtag they'll talk about it acting like a shift register and that analogy is great if you already understand how it works but if you don't understand how it works it's extremely confusing right because you think well it's a shift register i'm just feeding data in and i'm just clocking it back out to me so what is that what does that mean what people forget to mention is that they are linked together like a shift register but essentially you shift data in navigate the state machine to a different state then you shift data out and through doing that you've changed the data that's going to come back out on tdo so the tap or the test access point similar to the dap that we talked about is what we are going to be interacting with with that physical interface so every internal register access that we're going to talk about can be accessed through what's called the tab controller and the jtag specification defines the state machine and the registers that this controller interacts with and so everything on top of this right memory read memory write all the components that we actually want are implemented outside of the jtag state machine that we're going to talk about so the core jtag state machine is used to read and write to a specific set of registers now what those registers do is entirely up to the target chip that you're looking at and that's where it can get really confusing and so here's an example of this state machine right so we've all seen this diagram or i assume a lot of you have probably seen this diagram if you've tried to look at jtag before and so as far as timing goes and how data is read on through this state machine data is valid on tdo when the on the falling edge of clock in certain ir states now that is a mouthful right i don't expect anybody to understand that like right now and we're gonna go through all the states so that you understand what that actually means um data is not shifted in when this shift state is entered so you enter the state and then you start i'm pointing to the monitor like you can see that i'm sorry so data is not shifted in in this state um basically you enter the state and then data is shifted in and so it is shifted in on in the exit state and again that's a lot to take in that's a lot of sort of timing stuff and definitions that you're not super quite familiar with yet so let's just try to get through to the core pieces which is this so the jtag specification in its entirety defines a state machine that you can use to read and write to two registers just two there's no apps there's no dapps there's none of that stuff all that stuff gets implemented you know at a kind of a different level but at its core the jtag state machine lets you read and write from instruction registers and data registers now when i say instruction and data i'm not talking about like a harvard architecture kind of thing right there's a there's a register that's used to denote an instruction that's going to take place and there's a register that's used to provide additional data for that instruction that's going to take place so think of a read operation right what do you need if you want to do a read operation you need a target address so you would put in the instruction register the read command and in the data register you would put the address you want to read from and so by writing to those two specific registers you would perform the read and then shift the data back out and we're going to show an example of how that works but these registers define how you interact with the tap of the target cpu right and so every cpu has a different essentially a different implementation and what different and different definitions for the instruction registers now the spec defines that id code is um a certain uh instruction value and that bypasses a certain instruction value and so again we talked about you know when you're reverse engineering you want to boil something down to its core pieces we know that those two things have to be defined in order for the uh tap controller to be jtag compliant so those are the two things that we'll focus on but for now on the whole what you guys need to understand is that the jtag tab controller interacts with two registers the data register and the instruction register and data is shifted in on tdi as the name would imply and it shifted out on tdo again as the name implies so we talked about the instruction register and so these are the this register is written to to tell the jtag state machine like what operation you want to perform and so the standard defines the bypass instruction the ex test instruction the sample preload instruction and the id code instruction now most uh implementations of this that you're going to look at you'll definitely see id code and bypass the other two are a bit more tough to maybe define or see i'm just saying in the things that i've looked at id code and bypass have been the two that i've always been able to find so like like i said before this instruction register is used to determine what operation is actually going to be performed right whether it's a read or a write or you know querying the status or what have you and this is all going to be defined by the cpu vendor and this is where like black box jtag reversing becomes pretty difficult because it is just a black box right you write to this instruction register you write to this data register and you just try to see what comes out and you're just kind of hoping for the best now there are tricks that you can do to infer more about what different registers do and how they behave and we'll you know we might get to that we probably won't but uh the instruction register is used to tell this the tap or the debugging core what you want to do the data register are used to basically provide additional information to the instruction register and so this is another thing you'll hear people say and it's 100 true but to me it was very confusing initially was that the instruction register the instruction register selects the data register yes that makes total sense but you might think about it too much and think like wait then why do we even have it if it just picks a data register why can't i pick a data register well the instruction register when that gets selected that loads up a particular data register it basically maps to a particular data register right so that is what people mean like when they say that the data the instruction register selects a data register and so again we talked about it can be used for things like target address or a target value if you're trying to write but the the data register is you know read write so when you perform an operation and you want to look at the result you read from the data register for that operation and i think we'll get to a point where we'll walk through the state machine and this will make more sense so again sorry i'm talking really fast i'm trying to get you guys through the core pieces here so i'm sorry please toss questions in and i'll uh i'll answer them at the end if we have time the state machine defines like the core piece of jtag functionality uh each node in the state machine has a different purpose and we'll talk about what those are tms is used to basically navigate between these different state machines and by interacting with the state machine you get access to those two core registers we talked about right the instruction register and the data register and by reading and writing to these registers we can eventually perform the desired debug operations that we care about so state machine navigation uh the state machine is navigated by the clock and the tms signal so the clock signals when you sample when tms gets sampled tms controls which state in that machine it jumps to next so every clock cycle tms is sampled and the state machine is updated now if there's a tap reset pin that's asserted on a clock cycle you will jump to the default value for the state machine you'll jump back to the initial state so test logic reset first state in the state machine is the reset state for the tap so this is where it starts um you can get to this state machine from any state by holding tmsi high for five clock cycles and this is all defined in the specification and when this happens this is important to know when this happens the id code instruction is loaded so what that means is that the data register now contains the id code for the chip and this is what things like the jtagulator use to try to find the state of the uh controller right or try to find what pins or what so essentially the algorithm is you hold tms high you clock in you know five clock cycles you navigate to the uh shift dr state and read it and look for an id code and that's there's a really great paper called a black box jtag reverse engineering i'll try to grab a link to it and drop it in the chat um that defines this very very well so let me grab this real quick it's from uh i don't wanna i don't wanna if i try to pronounce the author author's name i'll probably butcher it but here is the link to the paper um and this will cover everything that we were going to cover today so this is a really great starting point for uh people that want to learn how jtag works from like a reverse engineering perspective and it's it's a really easy read it's written really well um it's a it's a great paper it's really great can't recommend it i really can't recommend it higher enough like if you're confused by you know what jtag is or what it does give this paper two or three reads uh and it's very short um but it's it's really it's really great um all right yeah so test logic reset is the default state of the state machine um and then you have run test idle this state literally performs nothing it's just for idling or for waiting if you're waiting for an operation to finish or you know something might take a certain amount of time you can return to that state so select dr scan this is basically telling the tap that or select ir scan it's basically telling the tab hey i want to select the instruction register or i want to select the data register so if tms is one so if tms is one we go here and then if we clock one again it goes here okay just so people are clear on how this state machine is navigated these numbers uh depict the state of tms when a clock cycle is read and i guess with that i think we are at i think we're at 7 15 i don't think yeah there's so much more to get through but in a nutshell that's there's a lot of it um there's a lot of this but uh that is uh and so what you might see let me just real quick uh before people head out if you're looking for you know potential headers let me switch over to the microscope here um this would be this we've got eight pins here lined up and there's you know four additional pins uh on top of it which are actually used uh for in system programming for this particular chip which is pretty neat but yeah you got four pins lined up like that uh pretty small pitch well it's actually just two millimeter it's not that weird but yeah you'll typically see you know more than six pins for a jtag header um if the header is not broken out the minimum amount you need are those four pins tms tck tdi and tdo and so that was the 15-minute speed run of of jtag i know we didn't really get to everything but you know read that paper that paper is great and uh you know reach out to me on twitter or wherever if you have any questions about about this kind of stuff i'm happy to help well matthew uh thank you for presenting such an engaging engaging program for us there was a lot of information uh but you didn't let it become an overwhelming flood of data uh and i i have to say you have a great cadence for presenting very technical material and seeing you breeze through this debugging session i can tell that you're a very patient person [Laughter] but i'd like to invite everyone to continue the discussion on the hackaday.ios webpage in its public chat and i posted it in the group chat on the side here of the zoom room and i'd like to say uh thank you to all the attendees uh you know this is really a community that rallies around sharing knowledge uh giving positive feedback and that's one of the things that's made remote con a really great experience uh so uh you'll be able to catch and view uh the other discussions and videos that you may have missed on hackaday's youtube channel and with that uh i'd like to thank everyone for participating in ramonacon uh hope we'll hope to see you again or very soon so uh keep a look out for our social media accounts and uh yeah all right everyone thank you again yeah thanks for thanks for hanging out thanks for the questions everybody this was great you
Info
Channel: HACKADAY
Views: 11,974
Rating: 4.8935361 out of 5
Keywords:
Id: hWYzgw0WhYU
Channel Id: undefined
Length: 122min 12sec (7332 seconds)
Published: Sun Nov 08 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.