[00:00.000 --> 00:01.460] Can everyone hear me? [00:02.540 --> 00:04.220] My name is Travis Goodspeed. [00:04.540 --> 00:08.860] I'm a student at the University of Tennessee and I work for Oak Ridge National Laboratory. [00:09.480 --> 00:22.120] This is a side project of mine that began during my Toorcon 2007 project which was a stack overflow exploit for MSP430 based wireless sensor nodes. [00:23.000 --> 00:29.960] So where these nodes are deployed and where they're running certain types of microprocessors you can inject code into them just as you would a computer. [00:31.880 --> 00:34.560] But unlike a computer you have no operating system. [00:34.820 --> 00:38.460] You have no address space layout randomization. [00:38.660 --> 00:43.100] You have none of the defense mechanisms that PCs and servers have built up over the years. [00:43.740 --> 00:48.480] It's just flat memory space, single application. [00:49.300 --> 00:53.180] Perhaps there are some standard libraries but there's no OS as you know it. [00:54.280 --> 01:00.820] So this talk is going to describe methods of reverse engineering software that you've taken from such a platform. [01:02.120 --> 01:12.000] And rather than introduce reverse engineering itself, I'm going to assume that you know the basics from, say, taking apart a PC program in IDA Pro. [01:12.380 --> 01:16.660] That you understand C functions and the C programming language. [01:16.660 --> 01:19.320] That it's turned into assembly language and all of that stuff. [01:19.900 --> 01:24.160] But that you have no experience with wireless embedded systems. [01:24.940 --> 01:26.960] Or the MSP430 in particular. [01:28.260 --> 01:37.240] So I'm going to focus on those ways in which this platform is different from a PC and the ways in which the tools are different from a PC. [01:37.860 --> 01:39.580] IDA does not support the MSP430. [01:40.440 --> 01:44.540] So I've been working on a Perl script called MSP430 Static. [01:44.920 --> 01:48.380] Which is used to reverse engineer software for the platform. [01:50.460 --> 01:55.740] So the MSP430 itself is a 16-bit RISC-ish microcontroller. [01:56.660 --> 02:02.320] And for those of you familiar with the principles of RISC, it was supposed to have single addressing mode. [02:02.900 --> 02:06.860] Well, not single addressing mode, but single way of fetching and storing to RAM. [02:07.340 --> 02:09.940] So if you want to read anything from RAM, you use a load. [02:10.000 --> 02:11.980] If you want to write anything to RAM, you use a store. [02:12.740 --> 02:20.720] Your addition, your multiplication, your XOR, other opcodes cannot access RAM directly. [02:20.840 --> 02:22.040] They can only access the registers. [02:22.520 --> 02:24.460] On the MSP430, this isn't true. [02:24.640 --> 02:27.200] You've got complicated addressing schemes. [02:27.300 --> 02:33.920] And this is necessary to fit firmware within the limited RAM and Flash memory of the device. [02:35.740 --> 02:38.480] You can get MSP430 static at SourceForge. [02:38.700 --> 02:41.100] It's msp430static.sf.net. [02:41.620 --> 02:43.700] It's a poorly written Perl script. [02:43.940 --> 02:45.180] I apologize for that. [02:45.380 --> 02:50.220] But it works, and its design is being cleaned up. [02:51.340 --> 02:54.000] This is the device that we'll be hacking today. [02:54.000 --> 02:56.060] It's the Telos-B. [02:57.140 --> 03:00.180] The design came out of the Berkeley Moat project. [03:02.820 --> 03:11.820] As you can see on the top, there's a USB plug that just gives you a USB to serial port, which runs straight into the microcontroller. [03:12.580 --> 03:21.200] On the left, if you see that copper tracing around the chip, that's an antenna. [03:21.200 --> 03:26.160] And the chip that it wraps around is a ChipCon 2420 radio. [03:27.160 --> 03:34.540] It uses the 802.50.4 protocol, which underlies Zigbee and ISA100 and various other low-powered schemes. [03:35.360 --> 03:38.100] This is much more low-powered than Bluetooth. [03:38.620 --> 03:43.140] And it doesn't specify modes of maintaining a connection. [03:43.300 --> 03:47.440] It doesn't specify anything except how to get a packet from one device to another. [03:48.040 --> 03:51.740] Everything else is built on top of it by networking stacks. [03:51.940 --> 03:53.340] And you can pick and choose your networking stack. [03:53.680 --> 04:01.360] When you compile software for this platform, you just specify which stack you'd like to use, and it builds everything in. [04:01.540 --> 04:08.880] If you want to switch from, say, Zigbee to RAW 15.4, that's one option on your make command. [04:12.100 --> 04:16.200] And this is because the standards haven't really solidified yet. [04:16.340 --> 04:21.280] You can't say that if you're doing a commercial protocol, you have to go with Zigbee or you have to go with ISA100. [04:23.980 --> 04:25.820] And you need to be able to switch on a whim. [04:27.260 --> 04:31.680] So, the first thing that you do is attach a JTAG connector. [04:31.860 --> 04:35.840] And I'm going to go through this rather quickly because it's just a bunch of photos. [04:36.040 --> 04:39.420] There's this U8 connector on the circuit board. [04:42.080 --> 04:48.280] Now, U8 is a condensed connector for both JTAG and a serial port. [04:49.600 --> 04:52.020] To access it, you just pop it off of the battery. [04:52.380 --> 04:55.080] You break apart one of these multi-pin connectors. [04:56.220 --> 05:00.660] You feed them through after plugging them onto the translator board. [05:01.880 --> 05:02.640] Solder them. [05:02.800 --> 05:07.440] And they'll stay in a nice, neat row like this as if they were still surrounded in the plastic packaging. [05:08.880 --> 05:13.500] Which you cut off with pliers if you don't have the proper sizing as I didn't. [05:14.460 --> 05:16.520] You then add an adapter board. [05:16.520 --> 05:18.040] This gives you two plugs. [05:18.440 --> 05:21.000] In the background is a serial port. [05:21.140 --> 05:22.800] In the foreground is the JTAG port. [05:23.520 --> 05:25.700] You run that into USB-FET. [05:25.960 --> 05:29.500] You can purchase one of these from Texas Instruments for $50 to $100. [05:30.240 --> 05:31.940] It connects over a USB port. [05:31.940 --> 05:33.220] Works perfectly on Linux. [05:35.540 --> 05:37.320] You just plug it into the board. [05:37.580 --> 05:44.340] And then you actually run GDB as you would on a regular PC program. [05:44.340 --> 05:49.300] So, but instead of attaching to a process ID, you attach to the physical device. [05:49.860 --> 05:54.460] So, you just run a script that says grab the device off of this USB port. [05:54.660 --> 05:58.840] And you get your GDB command line with the present program counter position. [05:59.060 --> 06:04.480] And everything that you would expect on a UNIX process. [06:05.720 --> 06:09.260] You run a dump command to dump memory just as you would in UNIX. [06:09.980 --> 06:12.040] This gives you an Intel hex file. [06:14.000 --> 06:15.600] The Intel hex file... [06:16.280 --> 06:17.960] I just showed the head of it here. [06:18.240 --> 06:20.320] So, this will be the beginning of RAM. [06:21.400 --> 06:26.220] And every single line of this can be easily interpreted by script. [06:26.640 --> 06:35.480] So, beginning with this line, the colon just says this is a line of the file. [06:35.480 --> 06:39.940] 10 is the length in hexadecimal as a single byte. [06:40.480 --> 06:42.240] So, 1, 0 is 16. [06:43.280 --> 06:45.520] There are 16 bytes worth of data. [06:45.880 --> 06:47.580] 32 nibbles, 32 characters. [06:48.140 --> 06:49.720] Following that is the starting address. [06:50.840 --> 06:56.640] 200 happens to be the beginning of the address range that we instructed it to dump. [06:56.760 --> 06:57.960] And it's also the beginning of RAM. [06:58.860 --> 07:00.800] Followed by that is the data itself. [07:01.020 --> 07:02.380] Followed by that is a checksum. [07:02.380 --> 07:10.960] So, if the checksum weren't enforced, you could almost use this as a plain text hex editor equivalent. [07:12.580 --> 07:14.240] We'll jump through those. [07:15.040 --> 07:18.040] You disassemble it using GNU binutils tools. [07:19.160 --> 07:21.320] Utils, just as you would normally. [07:22.000 --> 07:23.400] On a PC program. [07:23.600 --> 07:24.600] Just OBJ dump. [07:25.020 --> 07:26.280] Specify the architecture. [07:27.200 --> 07:29.180] Specify the input file. [07:29.460 --> 07:30.440] Dump it out to a script. [07:31.380 --> 07:34.700] You then read that into MSP430 static. [07:35.820 --> 07:38.180] Which I'll call M4S to save some syllables. [07:39.060 --> 07:42.200] So, it reads it in and it populates an SQL database. [07:42.620 --> 07:45.140] With everything that's found within that image. [07:46.360 --> 07:52.020] On a PC program where you have 4 gigabytes of potential space. [07:52.020 --> 07:54.080] That would be suicide. [07:54.420 --> 07:55.920] It would kill performance. [07:56.420 --> 07:59.340] And the application would become unusably slow. [08:00.360 --> 08:02.340] With even a moderately large program. [08:03.200 --> 08:05.200] We're dealing with a 16-bit microcontroller. [08:05.640 --> 08:08.780] Until you get into later extensions to the platform. [08:09.900 --> 08:13.040] You can only have 64 kilobytes of total memory. [08:13.040 --> 08:13.820] That's code. [08:13.960 --> 08:14.520] That's data. [08:14.660 --> 08:15.200] That's IO. [08:16.340 --> 08:17.020] RAM. [08:17.320 --> 08:17.840] Everything. [08:18.520 --> 08:22.860] And it turns out that this is manageable in an SQL database. [08:23.120 --> 08:25.080] Even before you do proper indexing. [08:27.160 --> 08:33.620] So, you communicate with M4S by using a dialect of SQL. [08:33.620 --> 08:38.200] So, you give it SQL queries and it gives you results. [08:38.700 --> 08:44.040] There's some changes in syntax to make things like hexadecimal addresses easier. [08:44.560 --> 08:46.740] And there's extensive scripting support. [08:46.860 --> 08:48.420] So, you can add a script in shell script. [08:48.740 --> 08:50.700] Or Perl. [08:51.060 --> 08:51.660] Or SQL. [08:52.140 --> 08:52.980] Those sorts of things. [08:54.960 --> 08:56.340] This is a macro. [08:56.560 --> 08:59.640] If you type in .memmap.gd.png. [08:59.640 --> 09:03.580] And you pipe the output into a .png file, you get this image. [09:05.160 --> 09:07.460] This is actually a bitmap of all of memory. [09:08.700 --> 09:10.680] The upper addresses are at the top. [09:11.400 --> 09:12.800] Lower addresses are at the bottom. [09:13.660 --> 09:16.500] I'm not sure if it's visible from the display. [09:16.520 --> 09:18.860] But at the very top right, there's a green line. [09:19.660 --> 09:21.880] That green line is the interrupt vector table. [09:22.760 --> 09:26.860] That's a set of pointers that are jumped to when an interrupt is struck. [09:29.180 --> 09:31.040] Beneath that you have flash memory. [09:32.900 --> 09:37.280] And you can see by the display that most of the flash is black. [09:37.600 --> 09:38.640] That means that it's unused. [09:39.880 --> 09:46.000] The flash is allocated by GCC beginning at the bottom of flash, working its way upward. [09:46.320 --> 09:49.140] And flash itself begins just above RAM. [09:49.360 --> 09:53.000] With a minor strip of unusable memory in between. [09:53.600 --> 09:57.280] The blue dots are addresses which are referenced by code. [09:57.620 --> 10:03.660] And there's a bit of noise in this because some of the code is junk RAM that was misinterpreted and disassembled. [10:07.150 --> 10:14.850] Now within the RAM, you've got... you see that bar of blue where addresses are constantly referred to. [10:15.890 --> 10:18.710] That's actually the serial bootstrap loader. [10:18.850 --> 10:22.770] It's a program which exists in masked ROM. [10:22.970 --> 10:23.710] Cannot be changed. [10:23.910 --> 10:27.550] Ships on every single MSP430 except for the very lowest end models. [10:28.190 --> 10:33.350] And it allows you to program the chip without purchasing the JTAG adapter. [10:33.350 --> 10:43.790] You can buy an FTDI USB2.2 QR converter, run some wires, send the initialization code, and load everything up. [10:44.370 --> 10:47.790] The very bottom, you'll see IO. [10:49.170 --> 10:55.210] Now IO isn't actually included in this image because we didn't dump it when we gave it the range. [10:55.210 --> 11:00.030] We said begin at 200, which is RAM, and work your way up to 4Fs. [11:01.650 --> 11:03.390] But there are still references to it. [11:03.610 --> 11:10.050] The blue dots, once again, are pointer targets. [11:11.350 --> 11:17.250] So there are points in code where things are written to or read from the IO ranges. [11:17.250 --> 11:19.870] And that forms the blue lines at the lowest level. [11:19.870 --> 11:26.370] The blue lines in the BSL level come from tables which exist. [11:26.670 --> 11:33.570] Every time you have a switch statement, you have a table of addresses which are added to the program counter. [11:33.750 --> 11:34.830] And those show up as blue. [11:38.200 --> 11:42.380] A quick review of functions as they work on this platform. [11:42.920 --> 11:44.320] There's a call statement. [11:44.640 --> 11:47.940] And the call statement is usually followed by an absolute address. [11:48.600 --> 11:53.060] It doesn't have to be by the microprocessor, but it always is by GCC. [11:53.720 --> 12:05.380] So unless you're doing custom assembly or you're, say, doing self-rewriting code, which I have done on this platform, you just give it an absolute address and it jumps to it. [12:05.440 --> 12:09.280] So that means that we have the entry address of every single function. [12:11.100 --> 12:14.520] And then we also have a return address which follows it. [12:16.720 --> 12:31.880] And if you look more closely at the output of any given compiler, and there are seven for this platform that are in common use, you'll find that every function is either the target of a call, an interrupt vector table entry, that's an interrupt handler, [12:32.620 --> 12:36.140] or it's used by a function pointer, and function pointers are exceedingly rare. [12:37.260 --> 12:42.680] You'll also note that every function ends after either a return or a return from interrupt instruction. [12:43.800 --> 12:46.540] And that is always after the last relative jump. [12:46.800 --> 12:50.200] There are no relative jumps between functions. [12:51.740 --> 12:56.360] This is partly caused by the compiler and it's partly caused by proper C coding methods. [12:56.500 --> 13:01.300] It's considered spaghetti code to have a go-to statement and one function jump to a label within another. [13:02.920 --> 13:05.280] It works, but God will condemn you for it. [13:09.520 --> 13:12.960] Now, we can do a search of all of the entry points. [13:13.240 --> 13:16.720] So you can do a select statement, this being the simplest type of query. [13:16.940 --> 13:22.280] If you say select the hexadecimal address of each function, it gives you a list. [13:22.300 --> 13:25.540] And these are the first two elements, or the first page of results. [13:25.780 --> 13:31.080] This is a large program that includes radio drivers and other such stuff. [13:31.080 --> 13:33.940] Now, flash run begins at 4,000 hex. [13:35.060 --> 13:39.000] And you can see that there's the function at 4,000 hex. [13:39.220 --> 13:41.460] That is the target of the reset vector. [13:41.700 --> 13:42.960] It always is. [13:43.080 --> 13:50.480] So when the chip powers on and the firmware has been compiled with GCC, execution always begins at 4,000. [13:51.580 --> 13:57.940] This is important because that 4,000 is also 1 16th of the password for the bootstrap loader. [14:00.320 --> 14:06.060] And by recognizing the behavior in the compiler, you can actually guess some of the passwords within the chip. [14:06.980 --> 14:10.320] Not well enough to break it quickly, but with other methods you can. [14:11.560 --> 14:17.180] Now, you'll also note these other addresses which occur before flash memory. [14:18.860 --> 14:20.200] That's the BSL ROM. [14:20.520 --> 14:28.540] That's the program that ships in masked ROM that you cannot erase on every single chip for loading software over the serial port. [14:29.180 --> 14:35.760] And they got dragged into our analysis because we included them in our range. [14:39.960 --> 14:44.540] Now, the BSL itself is an alternative to JTAG, and it's password protected. [14:45.340 --> 14:57.640] At Black Hat this summer, I'll be demonstrating a method by which, on the most recent versions of the chip, and very few prior, if any, you can break the password. [14:57.880 --> 14:59.980] The timing becomes non-regular. [15:00.720 --> 15:05.320] And by observing differences of a single clock cycle between... [15:06.100 --> 15:10.400] You're giving the last byte of the password, and it's telling you, OK, I've got it. [15:11.260 --> 15:14.820] You can actually tell how many bytes of your guess are correct. [15:17.740 --> 15:20.120] But details on that will have to wait until August. [15:23.220 --> 15:30.880] Now, once you read in this program and you've got these hexadecimal addresses, you can know some of them by experience. [15:31.020 --> 15:35.680] That 4,000 hex is always the entry point of a user program. [15:36.460 --> 15:39.560] But that doesn't tell you enough to begin reading the code. [15:39.560 --> 15:44.260] You'd have to search through thousands of bytes of code to find what you wanted. [15:46.140 --> 15:49.340] Now, if you think about how you write C code, you try to use libraries. [15:50.280 --> 15:53.120] You purchase libraries, perhaps they're open source. [15:53.700 --> 15:58.500] In the case of this system, all of the external chip drivers. [15:59.280 --> 16:01.000] They're libraries, and they're linked in. [16:02.260 --> 16:04.560] Now, they're not DLLs. [16:04.620 --> 16:05.640] They're statically linked in. [16:05.760 --> 16:07.440] Only the functions that you call are used. [16:07.940 --> 16:14.660] But because it's pre-compiled code, even though links are adjusted, the code is almost identical. [16:15.380 --> 16:21.360] And if you have a leaf function, if you have a function that does not call any other function, it is perfectly identical. [16:22.380 --> 16:24.140] So absolute value, for example. [16:25.120 --> 16:28.260] In assembly, you just check to see if the number is negative. [16:28.780 --> 16:32.460] If so, you invert it and you add one to make it positive. [16:33.200 --> 16:35.040] If not, you just return. [16:36.740 --> 16:48.440] On a given compiler, say GCC, every function that calls ABS, the absolute value function, will include that same string of bytes within its software. [16:48.980 --> 16:51.480] And we know the beginning, and we know the end. [16:53.080 --> 16:56.420] So a database can be made of these different functions. [16:57.480 --> 17:03.000] Now, of course, you can't just share the function code itself, because that would be copyright infringement. [17:03.920 --> 17:08.010] But a one-way hash of a copyrighted work is not itself a copyrighted work. [17:08.220 --> 17:10.080] And that's all we need to test for equality. [17:12.080 --> 17:17.360] So MSP430 static actually ships with a list of MD5 checksums. [17:17.800 --> 17:20.040] They're not cryptographically secure, but they work. [17:20.420 --> 17:24.340] Of functions that you might find within a given firmware image. [17:25.000 --> 17:26.720] So you load it up. [17:26.860 --> 17:28.500] You copy the firmware off. [17:29.360 --> 17:35.140] It can then run through and recover all of the symbol names of functions that it's already seen. [17:35.140 --> 17:38.040] So you just type .lib.import.hashed. [17:38.580 --> 17:39.620] This is a macro. [17:40.060 --> 17:42.360] You can see the code inside the source. [17:42.880 --> 17:43.500] You can change it. [17:43.600 --> 17:45.180] It's just a string in a database table. [17:46.160 --> 17:49.300] Then you type in .symbols.recover. [17:49.820 --> 17:52.000] And it gives you a not an error message. [17:54.120 --> 17:56.260] I conceded at the beginning that this was sloppy pearl. [17:57.520 --> 18:00.440] But the result is that when you do a select statement. [18:01.100 --> 18:04.880] You can see the names of every standard library function. [18:05.440 --> 18:07.120] That I have in my collection. [18:09.970 --> 18:11.950] And if any of you begin working with this. [18:12.030 --> 18:13.850] And you send me your hashes. [18:14.850 --> 18:16.250] I can add them to the list. [18:16.370 --> 18:19.350] And if anyone begins analyzing the same firmware that you're working with. [18:20.490 --> 18:22.070] Or any related firmware. [18:22.290 --> 18:24.010] Or any firmware made with the same compiler. [18:24.770 --> 18:27.530] They can find the names that you've given these functions. [18:29.610 --> 18:31.650] Now you can also do call graphs. [18:32.290 --> 18:35.490] This is a simple picture perfect one. [18:35.930 --> 18:40.590] Of actually the function that causes a stack overflow exploit. [18:41.830 --> 18:44.230] You'll note that there's the interrupt vector table at the beginning. [18:45.150 --> 18:49.790] All of the interrupts just go to like a no op function. [18:50.110 --> 18:52.350] That says we shouldn't be interrupting on these. [18:52.350 --> 18:53.570] Which is what the hell happened. [18:54.370 --> 18:57.570] But in it goes to the reset vector. [18:58.150 --> 18:59.550] And this is a different chip. [18:59.770 --> 19:04.470] So flash memory begins lower at 1100 hex. [19:04.650 --> 19:05.990] But it's still the very beginning of flash. [19:06.150 --> 19:08.950] A rule about the reset vector remains true. [19:09.830 --> 19:10.670] It calls main. [19:10.930 --> 19:12.270] Main calls these other functions. [19:12.890 --> 19:14.530] These other functions call string copy. [19:16.490 --> 19:21.110] Now if I gave you this image as something to break into. [19:22.230 --> 19:23.450] You couldn't get main. [19:24.370 --> 19:25.790] You would get IVT. [19:26.010 --> 19:27.910] You would get ector's end. [19:28.210 --> 19:29.490] You would get unexpected. [19:31.670 --> 19:33.330] You would get test put s. [19:33.710 --> 19:35.710] Which you could tell was writing to a debugger. [19:36.570 --> 19:39.990] And most importantly, you would get string copy at 11 ae. [19:42.550 --> 19:46.350] So you can audit programs that you have no source code to. [19:47.870 --> 19:49.650] For things like string copying. [19:50.390 --> 19:52.730] And then you know exactly which function to look at. [19:52.830 --> 19:54.630] And you know exactly which functions call it. [19:55.950 --> 20:04.170] So you only have to actually decipher two or three functions of machine language to figure out a large program. [20:06.630 --> 20:14.310] Unfortunately, this turns into a rat's nest for the radio firmware that we've been working with. [20:15.130 --> 20:22.550] You'll note that there's a focal point in the mid of the picture just above and to the right. [20:23.270 --> 20:26.310] You see all of those edges overlapping one another? [20:27.010 --> 20:32.610] Well, if we zoom in, that's nest-see-atomic and nest-see-atomic-start. [20:34.870 --> 20:37.630] These aren't threads, but they're close enough. [20:37.890 --> 20:40.230] So you have threads and they don't want to step over one another. [20:41.290 --> 20:43.410] So they're doing like a mutex. [20:43.710 --> 20:44.230] Okay? [20:44.350 --> 20:47.170] So the one task won't kill another task. [20:48.450 --> 21:03.330] And if you do some database queries to see how many are calling it, you see that of 577 total function calls, nearly 200 are to this mutex start, mutex end. [21:04.610 --> 21:05.790] So we can just drop them. [21:08.350 --> 21:13.010] And then when we do the count, we see that we're down to 378 functions, and it looks much cleaner. [21:14.730 --> 21:23.870] It's not clean enough for me to show the whole thing on the display, but you can then start zooming into individual functions because the atomics have been isolated. [21:23.970 --> 21:26.570] They're just sitting off in a corner and we're ignoring them for the moment. [21:27.710 --> 21:32.950] There's another macro which recreates the calls table after you've mangled it. [21:35.710 --> 21:44.730] Now, when you're trying to mess with the program, you want to figure out where certain functions are being called, or which functions are included. [21:45.090 --> 21:48.310] So in this case, we have a ChipCon 2420 radio. [21:48.810 --> 21:58.970] The operating system is TinyOS2, which was chosen because I like it, not because it's particularly affected by any of this stuff. [21:59.230 --> 22:08.990] So you can just do a search for anything with cc2420 in the name, and it returns every single function that's part of the radio driver. [22:09.590 --> 22:16.290] Because it's seen a similar function in one of the example programs of TinyOS that's in my collection. [22:20.450 --> 22:23.310] Now, you can also chase by I/O ports. [22:24.630 --> 22:27.510] This is a microcontroller, so you don't have an operating system. [22:27.530 --> 22:30.330] You don't have slash dev devices as you would in UNIX. [22:30.470 --> 22:32.490] You don't have context switches when you write to it. [22:32.530 --> 22:33.770] You don't have any of that stuff. [22:33.930 --> 22:38.910] You just write to a special address at the beginning of memory called a peripheral register. [22:39.910 --> 22:43.990] These are between 0 and 200 hex on the MSP430. [22:44.910 --> 22:46.010] These control I/O pins, I/O modules, which actually do the work of I/O for you. [22:50.330 --> 22:54.730] So if you want to do, say, a serial port, you can write it yourself using the pins. [22:54.890 --> 22:58.930] You can, say, raise the voltage, lower the voltage, measure the voltage. [22:59.090 --> 23:00.450] You can do everything you need to do. [23:00.710 --> 23:03.430] Or you can let a peripheral module do it for you. [23:03.430 --> 23:09.810] And then it does the implementation in hardware, and you can spend far fewer clock cycles working out the details. [23:11.170 --> 23:12.670] There are also timers. [23:13.610 --> 23:16.290] You can turn interrupt handling on and off. [23:16.370 --> 23:18.290] You can do all sorts of things with these registers. [23:19.230 --> 23:23.670] Upcoming chips are having USB device ports through these registers. [23:23.910 --> 23:25.590] They're having hardware AES. [23:27.050 --> 23:38.470] So within this little $3 microcontroller, you can do AES encryption just by writing your key to one place in memory, writing a packet to another, and then reading the packet back out from that same address. [23:40.470 --> 23:43.570] But if you look at the data sheets, you get a list of all of these addresses. [23:43.730 --> 23:44.210] They're in hardware. [23:44.330 --> 23:45.070] You can't hide them. [23:45.110 --> 23:47.150] They're not remapped by the operating system. [23:48.110 --> 23:50.530] They're not English names or anything like that. [23:51.310 --> 23:53.010] So you can do a select statement. [23:55.070 --> 24:04.170] You can say, show me all of the CC2420 functions and which address in memory they write to. [24:05.750 --> 24:06.990] And that gives you a list. [24:09.450 --> 24:12.230] And as you see there, those addresses are within RAM. [24:12.590 --> 24:13.970] Those are global variables. [24:16.370 --> 24:19.190] Which are quite useful when you're trying to change the behavior of the program. [24:19.190 --> 24:21.410] But beneath that are the peripheral registers. [24:22.570 --> 24:31.130] So you know which pins the CC2420 is connected to, even if you don't have any hardware to work with. [24:31.550 --> 24:40.050] And further, you know exactly which function to look at to control that I/O. [24:40.050 --> 24:47.390] You know that CC2420 received P reads and writes the I/O. [24:47.430 --> 24:51.530] registers, which you can find from the documentation. [24:52.750 --> 24:58.370] It's a bit hard to read from that there, but it accesses port 1 interrupt enable. [25:00.070 --> 25:01.990] And then the port 1 interrupt flag. [25:02.130 --> 25:03.590] So it's controlling interrupts. [25:03.630 --> 25:07.130] And then after turning these interrupts on, there's an interrupt handler. [25:08.070 --> 25:12.810] So you look at the port 1 interrupt handler, whose name was likely not found by this. [25:13.450 --> 25:17.010] And then you can determine exactly what it's doing. [25:17.010 --> 25:19.970] You can replace that interrupt handler with another one. [25:20.230 --> 25:21.990] Change two bytes of the firmware. [25:23.030 --> 25:27.730] Patch something on in the unused black region from the memory map. [25:28.710 --> 25:30.750] Have that then jump to the original one. [25:30.870 --> 25:35.970] And you've just added an inline packet sniffer to the firmware. [25:35.970 --> 25:39.070] And because the regular firmware doesn't notice this. [25:39.170 --> 25:40.970] It's jumping over in the blink of an eye and everything. [25:43.410 --> 25:45.870] It will, say, do channel hopping for you. [25:46.010 --> 25:47.490] And then even if you don't know the protocol. [25:47.530 --> 25:51.090] Even if you don't know which frequency to tune the radio to. [25:51.470 --> 25:53.810] You're okay because it'll tune the radio itself. [25:55.150 --> 25:57.410] You can have it spit things out to you over a serial port. [25:58.610 --> 26:00.270] You record it and everything's good. [26:06.150 --> 26:09.550] Now, I'm just going to conclude with a few minor notes. [26:10.150 --> 26:12.890] And then just have me to take some detailed questions. [26:13.730 --> 26:17.310] Rather than the usual quick ones. [26:17.470 --> 26:20.890] So feel free to mention ports, hexadecimal, anything. [26:22.130 --> 26:25.330] So first, there's the issue of finding symbol information. [26:26.350 --> 26:29.730] This is actually the libc file. [26:31.090 --> 26:35.290] Of a commercial C compiler for this platform. [26:35.650 --> 26:36.730] So you can download it. [26:36.850 --> 26:39.530] You get, like, a 30-day evaluation. [26:40.170 --> 26:42.710] Or, I believe it's actually code size limited. [26:42.870 --> 26:44.910] So you can only compile a 4 kilobyte program. [26:45.190 --> 26:46.010] You got IAR. [26:46.830 --> 26:48.190] This is not IAR. [26:48.550 --> 26:51.770] If you have any experience with IAR's format, I would love to speak to you. [26:52.370 --> 26:54.990] This is Imagecraft, version 7. [26:55.830 --> 26:59.230] And I like Imagecraft because their format's so easy to read. [26:59.230 --> 27:00.610] You've got a DOS. [27:00.710 --> 27:02.030] You have DOS text files. [27:02.610 --> 27:03.210] CRLF. [27:03.390 --> 27:04.510] That's LF. [27:04.770 --> 27:08.230] So the CR is rendered as the control M in Emacs. [27:08.470 --> 27:13.470] And they're separated by UNIX text files with the .start and .end. [27:13.670 --> 27:20.010] So between every .start and .end, we have a record of a function within the library. [27:22.750 --> 27:27.450] Now, if you look at the M line, that tells you which source file this came from. [27:28.210 --> 27:30.410] In this case, abs.s. [27:31.370 --> 27:36.350] Despite the .s ending, I know that this is actually compiled... [27:36.350 --> 27:37.110] Oh, sorry. [27:37.410 --> 27:37.950] Scratch that. [27:38.210 --> 27:39.410] It's a .s file. [27:39.650 --> 27:41.190] So it came from assembly language. [27:41.430 --> 27:42.770] Might have been pre-compiled. [27:42.930 --> 27:43.490] Might not have. [27:44.490 --> 27:47.710] Beneath that, you see an .s entry. [27:48.010 --> 27:48.970] It's a symbol. [27:51.130 --> 27:53.190] The symbol is .abs. [27:54.170 --> 28:01.810] Commonly, system libraries prepend their functions with an underscore so that you can do it without the underscore to overwrite it. [28:04.090 --> 28:05.950] Beneath that, you have a .t line. [28:05.950 --> 28:13.470] And that .t line says that at an offset of 0 bytes, that's the first two 0s, you have the code beginning. [28:16.290 --> 28:19.610] 0e930334, 3e, e0, fff, etc. [28:21.130 --> 28:22.590] That's the actual machine code. [28:23.330 --> 28:29.670] When you link this, that is copied somewhere into your program, and a call statement is used to jump there. [28:29.670 --> 28:41.230] Then it takes R12, which is the first parameter in Imagecraft's compiler, and it makes it positive. [28:41.470 --> 28:42.310] And then it returns. [28:43.170 --> 28:47.930] You cannot call this from GCC, because GCC sends its parameter in R15. [28:49.030 --> 28:56.690] By watching which parameters are used in which order, you can often determine which compiler the code came from. [28:57.610 --> 29:09.250] Another way that you can fingerprint the code, if you see the ffff in the middle toward the right, that is an immediate constant. [29:10.710 --> 29:13.150] Now, the MSP430 has a unique feature. [29:13.790 --> 29:20.370] They realize that immediate constants would be needed a lot on a microcontroller, because you're always setting a bit or clearing a bit. [29:20.770 --> 29:24.110] And when you set or clear a bit, you're usually doing one, right? [29:24.870 --> 29:33.150] And that one is either zero, one, two, four, eight, or negative one. [29:33.530 --> 29:37.090] Negative one in 16 bits is the four fs. [29:37.990 --> 29:44.950] That can actually be encoded by use of a constant generator, and those two bytes can be cut out of this function. [29:46.510 --> 29:51.150] Imagecraft is the only compiler that... or assembler, rather, that assembles this way. [29:51.770 --> 29:59.670] All of the competing assemblers will take that fff, and they'll cut it out, and they'll cut that instruction from four bytes down to two. [30:00.790 --> 30:02.490] So you can identify it by this. [30:02.650 --> 30:05.470] You can also identify the lineage of the file format. [30:05.610 --> 30:10.210] This comes from an... I can't recall whether it's open source or free as in beer. [30:10.570 --> 30:15.490] But there's an assembler called AS430 that uses this exact same format. [30:16.870 --> 30:22.950] So from that we can determine that Imagecraft likely funded or purchased AS430. [30:24.550 --> 30:31.470] So all of these things can be determined about the file format, and once we have all of them, we can dump it. [30:31.550 --> 30:39.690] We can write out ABS, and then the MD5 checks some of the rest of it, and then we can identify ABS within anything that we see. [30:40.450 --> 30:44.590] But unfortunately, I only have working importers for Imagecraft and GCC. [30:45.890 --> 30:53.050] If you'd like to help out with IAR, I would quite appreciate it, as IAR is the most popular commercial compiler for this platform. [30:55.390 --> 31:07.070] Now, if you pop open a function, and I'm only going to do this for one because it's the sort of thing that you should do with pen and paper in private, or come get me and I'll walk you through it, it's bad for an on-screen presentation. [31:08.230 --> 31:12.330] We've got a byte-wise compare, and then a jump. [31:13.530 --> 31:16.370] And if the jump is not taken, then we enable interrupts. [31:17.610 --> 31:23.290] But using M4S, you can render that as an instruction flow graph. [31:23.810 --> 31:31.370] And you can see that execution begins at the compare, follows down, and if the jump is taken, it goes to the return. [31:31.410 --> 31:33.790] If it's not taken, it enables interrupts and then goes to the return. [31:35.950 --> 31:37.850] You can do graphs like this with timing. [31:38.350 --> 31:48.310] So if you're trying to analyze the timing of a complicated function to ensure that all branches have the same cost in clock cycles, you can do this. [31:48.310 --> 31:51.370] Just add up the edges between the vertices and you've got it. [31:53.670 --> 31:55.710] There's also an issue with switch cases. [31:57.190 --> 32:09.950] It puts a... you would think that if you have a switch, you'll have, say, three cases, all of which break, that it would render to 3F statements in machine language. [32:10.090 --> 32:10.950] It would look like that in C. [32:10.950 --> 32:21.510] In practice, what happens is that some compilers say that the program counter should be set to the foo element of an array of pointers. [32:22.230 --> 32:23.170] GCC does this. [32:24.590 --> 32:30.590] And the problem with this is that they just stick that array in the middle of your code. [32:31.210 --> 32:35.150] They don't... there's nothing marking it as special. [32:35.150 --> 32:39.470] So automated analysis tools will trip over it, thinking that it's code. [32:39.690 --> 32:45.110] And this caused some of the static blue lines in the unused portion of flash memory. [32:45.970 --> 32:52.850] And it's important to note that so long as this is being mistakenly interpreted, you can't trust every single byte that comes out. [32:53.350 --> 32:58.530] You'll always get a bit of false positives when you do, say, searches on poked addresses. [32:59.690 --> 33:09.370] Further, some other compilers, I'm not sure the name of it, but the one that TI uses to make the BSL masked ROM... [33:11.970 --> 33:16.270] I believe that the BSL actually predates Code Composer. [33:16.550 --> 33:19.750] And inside TI, they often use IR's product. [33:21.150 --> 33:25.430] You'll notice that the application notes come out for IR and then for Code Composer. [33:25.730 --> 33:28.500] And if you speak to TI's engineers, they've... [33:29.250 --> 33:33.550] Code Composer's catching up, but they still have a marked preference for IR. [33:34.230 --> 33:44.910] But whichever compiler they use internally for generating the BSL, and it might even be handwritten assembly language, they do an offset that's byte-wise. [33:45.730 --> 33:57.250] So instead of having two bytes for every element of the table, and it being non-relocatable, they only have one, and they can shove the code anywhere they like, without having to adjust references. [33:57.990 --> 34:02.330] This makes it smaller than GCC, and it makes it even more painful to interpret. [34:03.490 --> 34:10.430] Because I can't just do an automated interpreter for GCC style, because I want to catch the other compilers. [34:11.030 --> 34:17.070] And so features like that will be written, but automated handling of, say, jump tables is not yet working. [34:18.690 --> 34:23.350] Also, many of the operating systems, the term is being used loosely. [34:23.550 --> 34:27.270] It's really more of a compiler environment and standard library. [34:28.550 --> 34:31.570] That exists for these platforms, they do automatic inlining. [34:32.110 --> 34:34.590] Because stack memory is very precious. [34:34.590 --> 34:49.670] So if you have a function foo, which only calls bar, and bar is not called anywhere else within your code, it just appears in machine language as foo doing whatever bar would have done, with no intermediate call. [34:51.870 --> 35:00.930] This gets tricky because sometimes you can have the same library function, called only once, and then it doesn't show up. [35:00.930 --> 35:07.530] If in TinyOS you only do an absolute value call once, absolute value does not show up as a distinct function. [35:08.050 --> 35:10.670] It's just shoved right in the middle of your calling function. [35:13.370 --> 35:19.930] There's also an issue when writing patches for PC software. [35:20.210 --> 35:28.050] You can often get away with just shoving your code in, having it change bytes within memory, and continuing. [35:28.690 --> 35:31.270] And this works wonderfully in simulation. [35:32.850 --> 35:37.270] Because in simulation you can make Flash ROM rewritable as if it were RAM. [35:38.250 --> 35:44.590] You can do a simple make file in a C compiler, you have some preprocessor directives specifying the addresses that are going to be hooked. [35:45.730 --> 35:50.750] And it's easy to port it to a different version of whatever you're analyzing, because you only have to change those constants. [35:50.930 --> 35:54.770] You don't have to open up a hex editor and patch it and all of that stuff. [35:54.770 --> 36:07.210] But in hardware, because the code is in Flash and not RAM, while you can turn an individual bit from a 1 to a 0, you can only change a 0 to a 1 by changing the entire segment to a segment of 1s. [36:08.310 --> 36:16.730] And this becomes a complicated routine of copying everything to either another segment in Flash, or to RAM if you have room, wiping it, and then copying it back. [36:18.390 --> 36:24.730] And it gets very complicated if you're trying to do this to the interrupt vector table, because then you have to disable all of interrupts. [36:28.070 --> 36:33.390] And you have to circumvent a lot of the hardware limitations. [36:34.410 --> 36:39.410] It's also important to note that you cannot wipe Flash memory while you're executing from Flash memory. [36:39.410 --> 36:51.970] So whatever patching routine you have has to be executed from RAM, has to cut off interrupts first, has to shut down most of the chip, make its change, and then restart by jumping back into Flash. [36:53.230 --> 37:00.550] So in hardware, it's best to patch as few points as possible, and hopefully use a script for it. [37:03.010 --> 37:04.730] So, have you any questions? [37:05.930 --> 37:06.490] Yes? [37:07.030 --> 37:08.350] Can you just go to the microphone? [37:08.510 --> 37:09.070] Yeah, sure. [37:14.920 --> 37:17.180] Okay, so I'm like a total noob at this. [37:18.060 --> 37:24.720] I don't, you know, this is the first time I'm ever seeing this platform ever being talked about. [37:26.320 --> 37:29.840] What do we need to get started with this? [37:30.540 --> 37:41.300] Like, is this, because if I'm going to bring this back to my own room, how much is the microprocessor that you were talking about? [37:41.620 --> 37:46.260] Okay, so the microprocessor in quantities of three or fewer is free. [37:46.520 --> 37:47.220] You just sample it. [37:47.420 --> 37:47.800] Oh, really? [37:47.900 --> 37:49.960] If you want a development kit... [37:49.960 --> 38:03.980] You can sample any individual part number up to three, but there are many part numbers within a family, so you can make orders of maybe 50 chips for free. [38:04.760 --> 38:06.200] Be careful about that, though. [38:06.300 --> 38:06.600] They check. [38:06.620 --> 38:07.300] No, don't catch that. [38:07.580 --> 38:08.100] They won't. [38:08.640 --> 38:08.980] Right. [38:09.420 --> 38:11.440] So, don't cheat them on this. [38:11.600 --> 38:14.680] If you're getting free parts, do it to learn the platform. [38:14.900 --> 38:15.240] Okay. [38:15.240 --> 38:33.820] Now, as far as purchasing a development kit, for $20, you can get an in-circuit debugger, which does everything that the JTAG unit I displayed does for certain chip models over what they call spy-by-wire, as well as a target board with a chip on it. [38:33.920 --> 38:36.120] You can compile software with GCC. [38:36.140 --> 38:37.040] You can write it on there. [38:37.220 --> 38:45.040] They make a higher-end model, which includes two target boards, both of which have a more powerful chip and radios. [38:46.180 --> 38:47.300] This is only $50. [38:48.720 --> 38:50.920] There's some minor issues with developing in Linux. [38:53.440 --> 38:56.300] I've written articles on getting it to work in there. [38:56.600 --> 39:01.560] You essentially have to downgrade the firmware of two of the chips on the board. [39:01.840 --> 39:06.800] But you can make it compatible, and you can compile your firmware using GCC. [39:07.020 --> 39:09.080] You can use IR in UNIX. [39:09.080 --> 39:11.200] It all works perfectly under Wine. [39:13.340 --> 39:17.740] But the development equipment is very cheap, and it's a very nice platform. [39:18.140 --> 39:20.220] This does things that PIC could only dream about. [39:21.840 --> 39:23.320] 16-bit rather than 8. [39:23.920 --> 39:24.380] Hmm? [39:24.700 --> 39:26.220] 16-bit rather than 8. [39:26.920 --> 39:28.120] I'm sorry, I couldn't catch you. [39:28.600 --> 39:30.680] GMSP430 is 16-bit rather than 8. [39:31.480 --> 39:32.040] Right. [39:32.440 --> 39:36.640] And you have actual RAM with stack in RAM. [39:36.640 --> 39:41.140] It's von Neumann architecture, so you can do rewritable code, or self-rewriting code. [39:41.360 --> 39:45.100] You can have code that just spits out bytes and then jumps to them and executes them. [39:45.960 --> 39:47.240] And you can't do that on a PIC. [39:47.760 --> 39:53.120] You have as deep a stack as you have free memory. [39:53.300 --> 39:58.200] You can do all sorts of fancy stuff that a PIC cannot do for about the same price. [40:00.200 --> 40:00.640] Okay. [40:00.940 --> 40:02.180] So does that answer your question? [40:02.360 --> 40:02.500] Yeah. [40:02.680 --> 40:04.260] I'm just thinking that... [40:04.260 --> 40:06.420] Could you not write a virus to this thing? [40:06.560 --> 40:07.080] Oh, I did. [40:07.700 --> 40:07.900] Oh, come on. [40:08.140 --> 40:08.440] Okay. [40:08.820 --> 40:09.480] That was fine. [40:09.960 --> 40:14.980] So I presented that at ToorCon 2007 and TIDC 2008. [40:16.060 --> 40:18.980] If you'd like to hear it, I can present it tonight or tomorrow. [40:19.880 --> 40:21.100] Well, get some sleep first. [40:21.520 --> 40:22.360] I'll sleep first. [40:22.700 --> 40:25.100] Who would like to see it tomorrow afternoon at... [40:25.100 --> 40:26.040] Name a time? [40:26.040 --> 40:26.440] Yeah. [40:26.800 --> 40:27.100] Definitely. [40:27.700 --> 40:28.060] Okay. [40:31.940 --> 40:32.620] Let's see. [40:32.740 --> 40:34.540] I think they're opening up another room in there. [40:34.660 --> 40:35.360] Yeah, they are. [40:35.620 --> 40:36.020] Right. [40:36.700 --> 40:40.020] So I'll do it at, say, 4 o'clock tomorrow. [40:41.720 --> 40:41.960] Okay. [40:42.340 --> 40:42.900] All right. [40:43.080 --> 40:44.040] Any other questions? [40:49.540 --> 40:52.770] So I'm using a solution now where it's taking days forward. [40:53.190 --> 40:55.170] So this isn't... [40:55.170 --> 41:02.860] Their AS chip has either been announced since I last looked for it or has not yet been announced. [41:03.070 --> 41:03.190] Okay. [41:03.440 --> 41:10.000] If you look carefully through their marketing literature, they do their block diagrams and all of that stuff before they make the official announcements. [41:10.250 --> 41:16.770] So you can see peripherals in their marketing pictures that don't yet exist in the marketing text. [41:17.040 --> 41:17.050] Okay. [41:17.150 --> 41:20.810] And don't yet exist in chips that you can order or look up the data sheets for. [41:20.810 --> 41:21.520] Okay. [41:21.790 --> 41:22.750] But it's... [41:22.750 --> 41:23.900] So essentially it's not for hardware. [41:24.150 --> 41:26.040] So it's not going to be... [41:26.040 --> 41:28.860] Well, if it works the way that multiplication does. [41:29.040 --> 41:31.420] There's no multiply instruction on this chip. [41:31.710 --> 41:37.480] You write your two factors into different registers. [41:38.110 --> 41:41.940] You hit an interrupt, and then two more registers have the result. [41:42.210 --> 41:43.770] Or one, depending upon whether you want. [41:43.940 --> 41:44.570] One clock cycle? [41:45.480 --> 41:48.230] There's one clock cycle at which the result is invalid. [41:48.500 --> 41:50.940] But on the clock cycle after that, you can grab the results. [41:51.590 --> 41:53.130] It's an incredible chip. [41:53.590 --> 41:55.920] And they did this without taking over another opcode. [41:57.880 --> 42:04.730] If you're interested in, say, multiplication on a chip without it, there's an excellent article on doing soft multiplication. [42:05.800 --> 42:10.330] And I've recently extended that to do soft multiplication with code rewriting. [42:10.550 --> 42:26.420] So you can call my code with whatever number you wish to multiply by, and it generates fixed point machine code in RAM that you can branch to to perform the multiplication. [42:28.070 --> 42:34.330] And something like that is only possible on von Neumann architectures like the 430. [42:34.440 --> 42:39.070] If you tried to do this on an 8051, you would have to do memory management tricks. [42:41.540 --> 42:52.590] The 8051 chip I'm working with now actually cannot modify its own code, because if you swap the code out, then you are no longer executing your own code to rewrite itself. [42:52.610 --> 42:55.460] And there's no other RAM available. [42:56.860 --> 42:59.520] But this architecture is none of that kludge. [43:00.880 --> 43:01.920] Any other questions? [43:02.480 --> 43:03.070] Yes? [43:03.290 --> 43:09.700] Have you tried to develop products in the CPU or not? [43:10.000 --> 43:11.200] No, I haven't. [43:11.440 --> 43:14.920] I have done work with them by, say, bus sniffing. [43:15.360 --> 43:24.840] I can stick to syringe needles into traces on the board and grab your AES keys as you send them from the CPU to the radio. [43:25.100 --> 43:30.100] Because in present designs, the radio does the hardware acceleration of AES rather than the CPU. [43:31.600 --> 43:37.540] And if you sniff it on the bus instead of over the radio, you get clear text as well as keys. [43:39.720 --> 43:48.980] There's a standard coming out which actually specifies that we're going to use AES and we're going to have a fixed table of 256 keys. [43:49.820 --> 43:55.940] And it should be noted that sending the keys in the clear over the bus might be an issue. [43:57.640 --> 43:59.240] And this isn't a secure environment. [43:59.400 --> 44:00.480] We're not talking about a toy here. [44:01.620 --> 44:06.580] Lots of people are making lots of mistakes in designing hardware of this type. [44:07.880 --> 44:16.420] And in the near future, software for analyzing microcontroller software will become essential to securing these devices. [44:16.420 --> 44:21.200] to determining whether or not what you purchased is secure enough for use. [44:22.900 --> 44:23.500] Yes? [44:23.520 --> 44:27.480] Are these guys in any way related to the debuting crypto people? [44:28.720 --> 44:29.320] No. [44:29.460 --> 44:30.000] Okay. [44:31.640 --> 44:32.720] Any other questions? [44:34.280 --> 44:38.060] Okay, so I will pencil in the talk tomorrow for four. [44:39.580 --> 44:43.480] Look at the itinerary to make sure that it's penciled in. [44:44.720 --> 44:45.860] A few announcements. [44:48.900 --> 44:51.420] Don't blow up the hotel or hurt people here. [44:51.660 --> 44:52.000] It's rude. [44:52.700 --> 44:53.960] Don't turn the TVs off. [44:54.140 --> 44:54.720] They don't like it. [44:57.040 --> 45:02.540] And then there's a solar compass for the human domain talk in the Azusa room. [45:04.040 --> 45:05.320] I don't know what it is. [45:05.460 --> 45:05.900] I'm just reading. [45:06.880 --> 45:07.560] Thank you. [45:24.080 --> 45:25.540] I just had a quick question. [45:25.540 --> 45:25.800] Yeah. [45:25.980 --> 45:26.400] Are you... [45:26.400 --> 45:27.900] Is there somewhere that you can... [45:27.900 --> 45:29.100] Do you see the screens anywhere? [45:29.400 --> 45:30.540] Do you have a presentation? [45:30.800 --> 45:31.080] Yeah. [45:31.280 --> 45:31.700] Yeah. [45:32.200 --> 45:32.320] Awesome.