[019] IT9919 Hacking - part 4 - Diving into the boot-ROM

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi and welcome back to the open tech lab if you've been watching this series of videos you'll know that I've been doing a series of tests and experiments on these two media processors on this board this is the innards of a lenka lkv 373 a media extender and it's used for capturing HDMI imagery and sending it across a network to a TV and both these chips have very little public information out in the open about it they're both made by ITV who release very little information about this with our MDAs so I'm doing a bunch of reverse engineering to see how much I can find out about these two processes and particularly this one u2 which captures the HDMI and encodes it in h.264 we've made quite a bit of progress in understanding how this is programmed but there are still some major mysteries that I'd like to in cover including what is the compression algorithm used in the flash chips that store the firmware and there is also a checksum in that firmware in those flash chips that I'd like to figure out what the algorithm for that is so I'm going to continue doing a bunch of experiments to see what mysteries we can uncover about these chips now one of the things that's been helping me along in this project has been this leased data sheet and the Dae Chi isn't publicly available from ite but I found by googling this date sheet for the IT 99 10 up on github on someone's repository and looking through this file it only gives us some vague high-level information about functionality of the chip the overview of the features a little vague block diagram showing what's inside it it give us a pin outs which is useful for trying to identify the chips you can check that the wiring matches one variant or another of this chip and then down in the middle here there's a bit more detail about these different functional blocks the chip has but nothing nothing that equates to a technical manual but you can try and figure out a few things by reading between the lines and comparing the information in here with various other bits of information that being gleaned along the way but it doesn't give us enough to actually program this device now one thing I found very interesting thing is this page here which has the memory map so it shows what the address space of the IT 9910 is actually populated with now I often find that if I'm trying to find out secret information about various Chinese products and chips it's well worth having a look on Baidu which I believe is largest search engine in China and if you just search it with a keyword or some kind of identifier or something nine times out of ten it will draw a blank but every now and again every once in a while we hit the jackpot as we do in this case the third link that comes up links through to this site and there's a few copies of this scattered around and what we get after it loads is this file here which if you look at it you can see this is a header file containing the registered decisions the addresses of the various registers for the I T in ninety nine ten and I've checked this through and it does indeed correspond with the memory Maps so although this isn't a technical reference manual for the register set inside this chip this certainly gives us a lot more information to understand what is being programmed when various bytes are being read and written from the addresses that are defined in this header so we now have a lot more detail on the structure of the IT ninety-nine tens memory and we also of course have the ability to write any custom software by patching the upgrader that's built into the upgrade package so it will be interesting to try dumping out the state of these various peripherals and see what they do or maybe manipulate them and see what we can do with that but before doing that one thing that I think it would be really interesting to try is this at the beginning here so you can see we've got these two columns memory map after booting a memory map before booting and the only difference between them is the address to which this ROM is mapped in so I think what this ROM refers to is a mask ROM that's built into the IT 9910 and this is used to load up the software from the SPI flash into memory and I'm assuming this is the tantalizing possibility that it contains the code necessary to do the decompression and also verify the checksum so we might be onto something here so I think the next step is to try writing some software that can dump out this ROM through you to see report and if we can do that maybe we'll find something really really interesting so this is the pie the script that I'm using to dump out the ROM and its centers around this function in the middle right dump firmware and it takes the original length cane upgrade blob and the upgrade of software that's built into it and modifies the upgrader to make it do what we want and the way it works is pretty simple it just has a loop which goes through and prints out using printf and it prints the address and then 32 bits of data or on every line and then so what the chip will produce is a big long spew of data in hexadecimal coming out of the serial port now one of the problems we have is that there's a watchdog built into the ite 99 tens which means that we only have so long before the system will kick in and reboot itself so whatever we do needs to be done within the period of time that's available to us so I engineered this thing so it can automatically reboot the system over and over and dump out a little bit more of the brama every time but as it turns out it wasn't actually necessary and this was a bit over engineered because the rom is small enough so it can actually be dumped out in ascii in a single sitting but it's pretty awesome that we have such control over the device that we can do these things to it programmatically with a simple python script now loading up are dumped out rom inside bin very can have a bit of a view of the structure of what's in this ROM and as you can see it's all quite homogenous there's not really any obvious signs of structure here there are not really any strings to speak of apart from right at the end I found these two strings K proc and sis no idea what they refer to but the rest of it all just seems to be executable code which is probably what we'd expect now just looking through the hex down here I've noticed something that is extremely promising because as we look through you can see s media Oh too embedded in the code so these are instruction op codes and these are bits of binary data which are the arguments of those op codes so I think what we're seeing here is some code that checks the signature for s media row two and similarly if we keep searching down there's an instance of s Mayor's here and there are a couple of instances of these strings buried in the code in different places so I think what we're seeing here is some inside the blob which is checking the signature s media row to is correctly present at the beginning of the flash image so this is extremely promising to see code like this handling these signatures here and certainly an indication that we should dig deeper now I'm reasonably optimistic about being able to make sense out of this thing because the total length of the ROM is only about 18 kilobytes so I feel like we have a sporting chance of being able to make sense out of it so here I have the file loaded up in object um and this is definitely code for the RISC processor just as we would expect but trying to get any more detail about what's going on here is quite difficult we have a bit of a haystack to pick through here now to help me get a better understanding of what's actually going on here I've written a few Python scripts to help me make sense as the output of object up including this one this is annotate registers and this takes the output of option and looks for any address values which relates are the addresses that were given in the header file we found on by do and then prints them into the text in a useful way so if we look at the output here instead of getting some incomprehensible absolute address instead we get some annotations that make this a little bit easier to read and understand and as we go through you can see references to GPIO s and various system ish registers I think the sort of thing we might expect this ROM to be manipulating so that's going to make things a little bit easier to understand now the other tool I've got is this tool here called call graph that takes the output from annotate registers and generates as the name suggests a call graph now in this architecture it's really nice and easy to see where function calls are happening and where they're returning back to so it makes it quite easy to figure out what functions are actually in this ROM which is nice and I'm getting some good output set so if I run this we get this graph this dot file which we can load up in graph is and I'll do that in a minute one comment I'd say about this is that I really really like using graph is it's a really quick way to rustle up a nice diagram of what you've got it's quite easy to make a script output the graph is dot format and if we load that up in X dot here you can see we have a structural diagram of what's in the firmware now if we have a look back at the leaked data sheet you can see this page it describes some straps that you can set high or low to configure the operation of the IT 9910 and it's got a few different things here but these two pins are dedicated to the boot mode and it describes four options one of them's reserved it can boot from an SD card or from North flash which I assume is our spi flash or it can boot by cooperative mode whatever that is so with all that in mind let's have a look at our dots diagrams so here we have the call graph and each of these boxes represents one function that has been picked out by the script and the arrows represent calls through two other functions inside the run now as we zoom in you can see what we've got in the labeling so we start off with the address that the function resides inside the ROM the number of instructions that it has and various other bits of labels that I've tried to pick out these are all the hardware registers access by each of these functions and I've also set the script up to label if the function references s mares or s media so in this code there are two references to s mares and s media these two functions here and this function here now looking at the thing as a whole one thing that's immediately noticeable is that all these functions here on the right and along the bottom make reference to the SD card controller which is a hardware unit inside the ite 9910 and of course the eye T 9910 has the ability to boot off SD cards and SD cards are a little bit tricky to communicate with so it's no surprise to see a fair amount of code involved with dealing with the intricacies of communicating with them so in our case because we don't care about SD cards at all we can completely ignore all of the functions around here which is a really nice state of affairs because it means we can eliminate great swathes of code from having to be considered so now let's have a closer look at this group of functions over here so we have this huge 1,000 instruction function here which has tons of functionality in it and it makes reference to these three functions here these little helper functions that have a couple of dozen instructions in each one and one thing that all four functions have in common is that they all make reference to the SSP which is the synchronous serial port which is another name for the SPI port which is a feature of the IT 9910 so it's looking extremely promising that this set of functions will be the code that loads code in from the flash memory and unpackage --is it and prepares it for execution so I've been trying to figure out the function of these three helper functions and these two are still eluding me but this one in the middle three one eight is used an awful lot and its purpose seems to be to load a single word out of flash memory at a given address and then it takes that word and puts it in a register R 11 now as I've been going along in this project I've slowly been accumulating more and more information about what goes into the s Media format found in the flash chips and to help make sense out of the things I know so far I've been working on this script called s Media dump which is a work in progress and as I discover more and more things I can use it to extract more and more meaningful content from the flash chip so if I run it you can see what information it gives us so we've got our s media chunk here which has some fields containing the header length which is a chunk of data that comes before the s mare's and then the length of the s mass itself right before the S Mars there's a couple of fields that come right before this tag here the checksum as we discovered earlier and the total unpacked length of the s mass data and then the s Mayer's data itself is divided into various chunks which have a little mini header of their own containing the unpacked length and the packed length and then there are a few zeroes padded on the end and that's it and then this script will also output the files for the s Mars assembled together from the chunks and the header which appears between the overall beginning of the file and the beginning of the S mass section okay so a lot of time has passed several months in fact and I've been quite busy with several other things but in the background I've been steadily chipping away at this bootloader ROM and I've made some quite good progress in understanding what's going on here which I will explain so the first thing I did was copy out the disassembly of the function into a text file and if we look down the file you can see there's about twelve hundred lines of code here and so to try and make sense out of it I started adding comments trying to annotate and thing I could find anything that appeared to make sense and I began to put labels in the locations where any jump instruction jumped into and by doing this you can slowly reveal the structure of this thing trying to make sense out of the execution flow and it helps a lot that my script is able to label up all the hardware registers that this code is accessing so that really makes things a bit clearer gives you a little hint to see what's going on but beyond a certain point it becomes harder and harder to really know whether this code is doing whatever we think it might be doing it's quite easy to get lost in this so the idea would be to be able to step through this code and see how it works in real life fortunately there is a way that we can do this and the way to do it is to patch the ROM image into the flasher software now the reason that this is possible is that in this architecture most of the time jump addresses are specified using relative addresses so for example you can see here this jump instruction has a ffs leader here which indicates this is a small negative number offset that this jump address goes to which means that this is position independent code and you can move it to any memory address and it will continue to work now as it turns out this isn't completely true when it comes to switched case statements these are implemented using jump tables and these do contain absolute addresses and these have to be patched to cope with the new location but apart from that if we want to move this code around and patch it into a new location for it to run in in general it works out just fine so the general method is that we take the normal flash upgrade software and that includes the S media payload at the bottom and the flashes software in the middle here and within that we have an implementation of printf and then there's some code up here that uses printf to print SDK version and this is the first message that gets printed out when this program kicks in when you do the upgrade so next we take the ROM and paste it into an area of unused memory in the image this area's filled with zeros and so we can take our ROM and paste it in here and within that we of the function the SPI flash loader function that we want to delve into so now we patch the SDK version printing code so that instead of printing SDK version we instead jump into the beginning of our flash loader function now if we run this the ROM function is now running and we can see what it's doing because I have a logic analyzer attached to the flash memory with sig ROK SPI decoding and we can insert deliberate crashes by patching this to crash or insert infinite loops to make it halt at various points or delay loops to space things out a bit and this allows us to try and put some indicators into different parts of this function to try and figure out what's going on and what messages to the SPI flash this corresponds to furthermore it's also helpful to be able to print things with printf which is possible to do we just need two things we need a place to store our printf strings here in this patched in date section and we need a place to store some patched in code now how this works is that we can now patch a single instruction within our flash loader function so that instead of doing its normal operation it will jump over to our patched in code now the first thing the patch Dinko does is save the states of all the registers to put them on the stack so we can restore them later and then it loads up the arguments to printf including the message string and we'll jump over to the printf that's in the main software over here let that execute and print out the message and then it will return back into our patched in data section we then reload all the registers that might have got clobbered by printf running set them back to the state as they were when they were running along normally inside the function and then we run the instruction that we overrode in here so that then we can jump back into the flash loader function here and it looks as if everything works the way it was meant to so this was a bit tricky to get right and was always a bit janky and unreliable but little by little I was able to figure out what the function is actually doing now trying to do all this patching by a hand would be completely impractical so I've been using Python scripts to synthesize images which makes it a bit easier to do all these experiments so now let's have another look at this breakdown at the structure of the s Media firmware so we start off with the eighth by s media row two tag followed by a four byte address here now this is the address of the offset at the beginning of this purple section and then we have this gold thing here this is the address at the beginning of the S mass data and this blue field is the length of the s path data so I discovered that the first thing the ROM function does when it starts up is that it reads through the fields of this header one by one and stores them away and then it encounters this blue section here which contains subjunctive and some copyright text and it ignores it completely and jump straight over it to get to this magenta section now it took me a while to figure out what this section contains but the ROM function has a series of loops and switch-case tables that it uses to iterate its way through this thing and after a while I discovered that this is some kind of micro code script that the ROM uses to initialize the MMP now the MMP is barely mentioned in the datasheet there's not much mention of it at all apart from its location in memory but I have a hunch that it is the multimedia processor or multimedia pipeline or something like that and I would assume that it does the heavy lifting for all the video processing so the Rob iterates through all this micro code until it encounters on X's instruction which indicates the micro code is finished executing and now it's time to process the s math section so the first thing the ROM function does is that it loads up the checksum value from SPI flash and saves it for later it then reads the s mares header that and the signature checks the signatures correct and then it iterates through loading up the chunks of SMS data one by one and having them all decompressed into RAM and then once it's done all that it then computes the checksum of the data it just load it and then it compares it to the expected value which it calculates now interestingly it appears that if the checksum is made out of all ones as in its -1 in value I think that it will skip the checksum check entirely so I haven't tested this yet but it seems like it might be a handy way to bypass the checksum completely anyway so now I bet you're really wondering what the mystery is of the checksumming algorithm and what the mystery is of the compression algorithm and we should be able to read it right out of the assembly code shouldn't we but that would be far too simple and it turns out that what this code does it just loads addresses into the registers of a hardware unit called the dpu and there's a few other usages the dpu in here and it uses this to decompress the firmware and it also uses it to check some of the firmware and there's basically no mention of it at all in the datasheet beyond its address range in the memory map so I think you'll agree that we have fallen well down the rabbit hole now we have this black box unit within the processor how on earth are we going to figure out how it works but of course we do have the ability to write pretty much any custom software we like so one obvious thing to try is just to try inserting some data into it and see what it decodes so I've been making use of my rig to fuzz the dpu and that means I use a script to generate large numbers of test cases with slight differences between them and for each test case it loads a hacked version of the upgrader that triggers the dpu with test data and prints out the results and the script then collects the results in a log file for analysis later on and then it triggers the reset button and then it does the process all over again over and over and over running test after test after test after test now unfortunately I wasn't able to figure out how to make the dpu run more than once after a reboot so every test case I run involves rebooting the system so running a single dpu test run takes about 20 seconds so far I've tested over 14,000 test cases with the dpu and I've collected all the log files in a corpus big database collection of the results stored in message pack format message pack is a bit like Jason but binary data it's really handy check it out if you haven't seen already anyway of those 14,000 test cases around 1400 of them decoded successfully without the dpu aborting halfway through so I've started trying to model the behavior of the decompressor with a Python script to try and make a simple decompressor and I've been able to make the script correctly decoded about 800 of those 1,400 test cases so how does the s mask impression work well from what I've discovered so far it's byte orientated it never uses unaligned bit strings and the S Moz data is made up of a series of chunks which are between 2 and 10 bytes in length and the first byte is a command byte you could call it an opcode which defines what the contents the chunk is going to be so for example we've seen chunks that have a command byte of FF these contain 8 literal bytes in a row in addition to literal bytes a chunk can contain various types of back reference where it reuses data previously contained in the buffer and a bunch of other weird things that I don't completely understand I tried to model them then more and more weird things keep emerging different types of extended back ref that seem to be present and different types of repetition and all kinds of odd things seem to happen depending on what the opcode is with not much pattern that I've been able to discern so far and the problem I'm having is that although I've modeled this with my Python scripts and I can decode 800 these test cases I clearly haven't got a correct understanding of how the decoder actually needs to work because my script doesn't have any predictive quality as I keep adding test cases to the corpus it just shows more and more ways that the script is not working so I decided this projects gone on long enough before I published any video so it was time start trying to share this with the audience and it's very very interesting getting your reactions and feedback from the work I've done in the previous parts and one question I had over and over was the question of whether this s Mouse compression corresponds to this algorithm in this github repository here for the small strings compression library and the answer is no I don't think it is that at all I think it's just a coincidence that this algorithm shares the same name but something else has happened that seems very promising indeed this guy who goes by a Bridgewater Aleister Bridgewater reached out to me in my github repository for this project and started noting down a load of observations he'd seen about the s masse compression scheme and he's made some really really good progress he's got some really great insights for things I'd missed in how this works and I handed over every piece of information I had and there's a bit of a collaboration going on this guy Alistair Bridgewater is doing some great great stuff and Camille transits key velociraptors chipping in as well so there's a really good little project going on here to try and figure out what this s mass compression scheme really is and by the looks of things it may well get figured out pretty soon so by the looks of things we are on the verge of finding out the answer to all kinds of interesting mysteries about this processor and if you're curious about it perhaps you want to chip in and try some things yourself so anyway I'm Joe Holdsworth if you enjoyed the content give it a like and subscribe and I want to thank everyone who's supporting my channel with donations it really helps me improve the quality of my content helps me get gear and helps me do what I'm doing if you want to donate I've moved my donations over to the SUBSCRIBE star and to PayPal and you'll find links to that down below along with the show notes where there are lots of links and all the background information for this video so thanks for watching and I'll see you next time on the open tech lab you
Info
Channel: OpenTechLab
Views: 14,943
Rating: 4.9849339 out of 5
Keywords: open source, electronics, software, hacking, programming
Id: SYksf7Cbp-Q
Channel Id: undefined
Length: 26min 47sec (1607 seconds)
Published: Sun Sep 01 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.