Howdy Y'all,
A paper of mine from S4/Miami, Low-Level Design Vulnerabilties in Wireless Control Systems Hardware, has recently been made publicly available by Digital Bond. Coauthored with Brad Singletary and Darren Highfill, it provides a detailed survey of vulnerabilities that might be found in the hardware and firmware of AMI Smart Meters and similar equipment.
Please note that the paper, written late last year, is now outdated in two respects. First, the self-propagating worm presented hypothetically in Section 3.1 is no longer hypothetical. Mike Davis has written one. Second, the System-on-Chip Zigbee devices advocated in the conclusion of Section 4.1 are not secure, as I have since demonstrated in Extracting Keys from Second Generation Zigbee Chips.
--Travis Goodspeed
<travis at radiantmachines.com>
Tampilkan postingan dengan label msp430static. Tampilkan semua postingan
Tampilkan postingan dengan label msp430static. Tampilkan semua postingan
Senin, 02 November 2009
Jumat, 14 November 2008
Speaking at 25C3
At the 25th Chaos Communications Congress in Berlin this December, I'll be presenting some new research in the security of the MSP430's serial bootstrap loader (BSL) as well as a nice little lecture/workshop combo on reverse-engineering the TI EZ430 development tool.
I intend to travel through France and England, returning in late January for S4, Miami. Please email me if you'd like to meet.
Cracking the MSP430 BSL
Day 1 (2008-12-27), 20h30 (8:30 pm) in Saal 3.
The Texas Instruments MSP430 low-power microcontroller is used in many medical, industrial, and consumer devices. When its JTAG fuse is blown, the device's firmware is kept private only a serial bootstrap loader (BSL), certain revisions of which are vulnerable to a side-channel timing analysis attack. This talk continues that from Black Hat USA by describing the speaker's adventures in creating a hardware device for exploiting this vulnerability.
While the previous part focused on the discovery of the timing vulnerability and its origin, this lecture will focus on the exploitation. Topics include a brief review of the vulnerability itself, PCB design and fabrication, the malicious stretching of timing in a bit-banged serial port, observation of timing differences on the order of a microsecond, and the hell of debugging such a device.
Repurposing the TI EZ430U
Lecture: Day 3 (2008-12-29), 12h45 (pm) in Saal 3
Workshop: Not yet scheduled.
USB devices are sometimes composed of little more than a microcontroller and a USB device controller. This lecture describes how to reprogram one such device, greatly expanding its potential.
At only twenty dollars, the Texas Instruments EZ430U is a bargain of an in-circuit debugger for the MSP430 microcontroller. The board itself is composed of little more than an MSP430 and a USB to Serial controller. The board's JTAG fuse is unblown, and full schematics are included in public documentation. This lecture will discuss the use of the EZ430U, not as a debugging tool, but as a development platform in and of itself. Topics will include the writing of replacement firmware, analysis of the default firmware, reprogramming the USB to Serial controller, and potential target applications.
--
Travis Goodspeed
<travis at radiantmachines.com>
Senin, 15 September 2008
Repurposing the TI EZ430U, Part 3
by Travis Goodspeed <travis at utk.edu>
of Southern Appalachia
The first installment of this series described a method of accessing the EZ430's MSP430 firmware by way of JTAG, while the second installment took a detour to discuss the TUSB3410 usb controller of the board. This third installment is concerned with the analysis of the green EZ430U firmware; that is to say, it is concerned with the firmware of the six-pin EZ430f2013 kit, which might differ from the four-pin EZ430f2013 kit and drastically differs from the red EZ430rf2500 kit.
Section 1, wherein we make general, even visual observations regarding the organization of firmware, as well as the locations of important objects.
Observe the following memory map, which was generated by the .memmap.gd.xview macro of msp430static.
In an m4s memory map, the X axis represent the less-significant byte while the Y axis represents the more significant byte. 0xFF00 would be the top left, and 0xFFFF would be the top right. As the interrupt vector table (IVT) of the MSP430f1612 ranges from 0xFFE0 to 0xFFFF, it appears as a green band in the upper right of the image. Entries within it all point to the upper red band, with addresses varying from 0xfb78 to 0xfdb0, in regular increments of 4. The only exception to this rule is the RESET vector at 0xfffe, which points to 0xfdaa.
Why such an arrangement? Each of these regularly-spaced interrupt handlers is a branch to a lower interrupt handler. The blue line that you see at the top of the black expanse is a second IVT, entries of which are called from above. 0xffe0, the DMA vector, point to a branch to &0xf7e0, which is to say that address which is contained within 0xf7e0. Similarly, 0xffe2 points to a branch to 0xf7e2. In fact, every interrupt except for RESET points to nothing but a branch to its equivalent in the table that begins 0xf7e0.
It should be clear, then, that not one but two programs reside in this image. The first-stage firmware, which rests at the top of memory, performs its own initialization when the chip is reset, but differs all interrupt handling to the lower firmware, which grows from the beginning of flash to 0xf7e0. It shouldn't be hard to instruct a compiler to build a second-stage firmware compatible with the first-stage, but it would be imprudent to spring into such a task without at least a casual analysis of the first stage.
Section 2, wherein we examine the first-stage firmware in depth.
The first-stage firmware is a bootloader which resides from 0xf800 to 0xffff in flash memory of an MSP430F1612. A quick search with MSP430static--which I'll refer to as 'm4s' for the sake of brevity--reveals that 30 functions have been found in this area. Fifteen of these, those in the range [0xfb78,0xfbb0], are merely branches to interrupt handlers in lower memory. The interrupt handler is a function which I'll call init() that resides at 0xfdaa, calling a config() function at 0xf828 to set registers to their proper values. The only call made by config() is to delay() at 0xf812 that uses nested loops to implement a timing delay.
I/O is performed by putbyte() and getbyte() functions at 0xfbc6 and 0xfbd2 respectively. These use USART0 in UART mode. This port is configured, as are many other peripherals, in the previously mentioned config() function.
As the purpose of this series of articles is to describe the process for writing a complete replacement firmware, I should mention that such information is to be found within this stage. Port 3 is especially important, as it is tied into both UARTS and I2C. As you'll recall from the early articles of this series, the TUSB3410 refuses to load with ports in the default configuration. By matching the configuration of the original firmware, we ought to be able to get something going.
To that end, Port 3 is configured as follows within the config() function.
Clocks and such must also be reconfigured, but I come bearing good news! There's an easier way, in that by relocating the IVT or reconfiguring your compiler, you can generate a custom second stage firmware without rewriting the first stage.
Section 3, wherein we examine the second-stage firmware in brief.
By comparison to the simple, neighborly firmware of the preceding section, the second stage firmware is gigantic and multi-tasking, with a rats-nest of function calls to a few key functions. Although it serves little immediate value, I'll cover second stage as an example of a few analysis techniques.
Which function calls are most popular, and what do they do? The .calls.top10 macro results in the following:
Note the sharp dropoff after the third. In a multi-tasking application, such as a TinyOS wireless sensor node, it would be logical to assume these to be mutex locks. In a JTAG adapter, however, it is much more likely that these serve an I/O purpose. Sure enough, all three are I/O related with 0x4f54 performing I/O through function calls and the other two doing it directly.
As I am not concerned with reverse-engineering the TI's proprietary debugging protocol, but rather only with making software capable of running on the EZ430 programmer, I'll delve no further into the second-stage firmware. Remember only the following: (1) That the IVT of the second-stage code resides at 0xf7e0, (2) that all else remains unchanged.
The question then becomes one of relocating the IVT, which may be accomplished either by altering linker scripts or by rewriting the firmware image before flashing it to the device. We shall begin with the prior method.
Section 4, wherein we rewrite the linker scripts of two popular compilers so as to generate our own second-stage code for this fine platform.
Moving the IVT is accomplished in GCC by forking msp430x1612.x to ez430u.x, then changing line 8 to the following:
Please note that, for no reason that I can fathom, the RESET vector of the second-stage IVT has been hard-coded to be 0x2502 in some places. You must set the .text section to begin at 0x2502, or the reset will land in the middle of a two-word instruction.
Section 5, wherein your author makes a shameless plug his upcoming appearance at the tenth annual Toorcon San Diego but provides little else of substance.
A fourth installment of this series will wrap up the replacement MSP430 code, concluding with a complete and commented `hello world' example for GCC.
of Southern Appalachia
The first installment of this series described a method of accessing the EZ430's MSP430 firmware by way of JTAG, while the second installment took a detour to discuss the TUSB3410 usb controller of the board. This third installment is concerned with the analysis of the green EZ430U firmware; that is to say, it is concerned with the firmware of the six-pin EZ430f2013 kit, which might differ from the four-pin EZ430f2013 kit and drastically differs from the red EZ430rf2500 kit.
Section 1, wherein we make general, even visual observations regarding the organization of firmware, as well as the locations of important objects.
Observe the following memory map, which was generated by the .memmap.gd.xview macro of msp430static.
In an m4s memory map, the X axis represent the less-significant byte while the Y axis represents the more significant byte. 0xFF00 would be the top left, and 0xFFFF would be the top right. As the interrupt vector table (IVT) of the MSP430f1612 ranges from 0xFFE0 to 0xFFFF, it appears as a green band in the upper right of the image. Entries within it all point to the upper red band, with addresses varying from 0xfb78 to 0xfdb0, in regular increments of 4. The only exception to this rule is the RESET vector at 0xfffe, which points to 0xfdaa.
Why such an arrangement? Each of these regularly-spaced interrupt handlers is a branch to a lower interrupt handler. The blue line that you see at the top of the black expanse is a second IVT, entries of which are called from above. 0xffe0, the DMA vector, point to a branch to &0xf7e0, which is to say that address which is contained within 0xf7e0. Similarly, 0xffe2 points to a branch to 0xf7e2. In fact, every interrupt except for RESET points to nothing but a branch to its equivalent in the table that begins 0xf7e0.
It should be clear, then, that not one but two programs reside in this image. The first-stage firmware, which rests at the top of memory, performs its own initialization when the chip is reset, but differs all interrupt handling to the lower firmware, which grows from the beginning of flash to 0xf7e0. It shouldn't be hard to instruct a compiler to build a second-stage firmware compatible with the first-stage, but it would be imprudent to spring into such a task without at least a casual analysis of the first stage.
Section 2, wherein we examine the first-stage firmware in depth.
The first-stage firmware is a bootloader which resides from 0xf800 to 0xffff in flash memory of an MSP430F1612. A quick search with MSP430static--which I'll refer to as 'm4s' for the sake of brevity--reveals that 30 functions have been found in this area. Fifteen of these, those in the range [0xfb78,0xfbb0], are merely branches to interrupt handlers in lower memory. The interrupt handler is a function which I'll call init() that resides at 0xfdaa, calling a config() function at 0xf828 to set registers to their proper values. The only call made by config() is to delay() at 0xf812 that uses nested loops to implement a timing delay.
I/O is performed by putbyte() and getbyte() functions at 0xfbc6 and 0xfbd2 respectively. These use USART0 in UART mode. This port is configured, as are many other peripherals, in the previously mentioned config() function.
As the purpose of this series of articles is to describe the process for writing a complete replacement firmware, I should mention that such information is to be found within this stage. Port 3 is especially important, as it is tied into both UARTS and I2C. As you'll recall from the early articles of this series, the TUSB3410 refuses to load with ports in the default configuration. By matching the configuration of the original firmware, we ought to be able to get something going.
To that end, Port 3 is configured as follows within the config() function.
f88e: bis.b #48, &P3SEL
f894: bis.b #16, &P3OUT
f89a: bis.b #16, &P3DIR
Clocks and such must also be reconfigured, but I come bearing good news! There's an easier way, in that by relocating the IVT or reconfiguring your compiler, you can generate a custom second stage firmware without rewriting the first stage.
Section 3, wherein we examine the second-stage firmware in brief.
By comparison to the simple, neighborly firmware of the preceding section, the second stage firmware is gigantic and multi-tasking, with a rats-nest of function calls to a few key functions. Although it serves little immediate value, I'll cover second stage as an example of a few analysis techniques.
Which function calls are most popular, and what do they do? The .calls.top10 macro results in the following:
163 4c3e 4c3e
151 4f54 4f54
142 4b6a 4b6a
29 4eca 4eca
28 6100 6100
27 2ba2 2ba2
24 8d0e 8d0e
24 a784 a784
20 5f4c 5f4c
17 756e 756e
Note the sharp dropoff after the third. In a multi-tasking application, such as a TinyOS wireless sensor node, it would be logical to assume these to be mutex locks. In a JTAG adapter, however, it is much more likely that these serve an I/O purpose. Sure enough, all three are I/O related with 0x4f54 performing I/O through function calls and the other two doing it directly.
As I am not concerned with reverse-engineering the TI's proprietary debugging protocol, but rather only with making software capable of running on the EZ430 programmer, I'll delve no further into the second-stage firmware. Remember only the following: (1) That the IVT of the second-stage code resides at 0xf7e0, (2) that all else remains unchanged.
The question then becomes one of relocating the IVT, which may be accomplished either by altering linker scripts or by rewriting the firmware image before flashing it to the device. We shall begin with the prior method.
Section 4, wherein we rewrite the linker scripts of two popular compilers so as to generate our own second-stage code for this fine platform.
Moving the IVT is accomplished in GCC by forking msp430x1612.x to ez430u.x, then changing line 8 to the following:
vectors (rw) : ORIGIN = 0xf7e0, LENGTH = 0x20Call GCC with the -T switch followed by your forked linker script, and the output will direct to the proper address. Use msp430-objdump to verify the address in your output. For further details, consult my article on Retargetting the MSPGCC Linker. In the case of the IAR compiler, the IVT range is defined near the end of lnk430F1612.xcl.
Please note that, for no reason that I can fathom, the RESET vector of the second-stage IVT has been hard-coded to be 0x2502 in some places. You must set the .text section to begin at 0x2502, or the reset will land in the middle of a two-word instruction.
Section 5, wherein your author makes a shameless plug his upcoming appearance at the tenth annual Toorcon San Diego but provides little else of substance.
A fourth installment of this series will wrap up the replacement MSP430 code, concluding with a complete and commented `hello world' example for GCC.
Senin, 17 Maret 2008
ImageCraft V7 Symbol Importing for MSP430static
by Travis Goodspeed <travis at utk.edu>
at the Extreme Measurement Communications Center
of the Oak Ridge National Laboratory
I just committed r38 of msp430static which adds support for importing symbols from ImageCraft V7 for MSP430. A short example follows.
I'll use the following C code, but any will suffice.
At this point, msp430static knows the name of every function in my image. Here is the callgraph of my program above.
Note that my examples are in Linux. ICC 7 works perfectly as both an IDE and compiler under Wine.
at the Extreme Measurement Communications Center
of the Oak Ridge National Laboratory
I just committed r38 of msp430static which adds support for importing symbols from ImageCraft V7 for MSP430. A short example follows.
I'll use the following C code, but any will suffice.
void main(){Compiling it yields many files. The two of interest are FOO.hex and FOO.mp. The former is imported by converting it to msp430-elf and dumping the resulting ELF file.
int x=0xFFFF;
x+=1;
x+=0xFFFF;
x+=abs(5);
}
karen% msp430-objcopy -I ihex -O elf32-msp430 FOO.hex foo.exeSymbols are then imported with the .symbols.import.ic7 macro.
karen% msp430-objdump -D foo.exe | m4s init
karen%
karen% m4s .symbols.import.ic7 <FOO.mp
karen%
At this point, msp430static knows the name of every function in my image. Here is the callgraph of my program above.
Note that my examples are in Linux. ICC 7 works perfectly as both an IDE and compiler under Wine.
Rabu, 27 Februari 2008
A Brief Tutorial for MSP430static
by Travis Goodspeed <travis at utk.edu>
at the Extreme Measurement Communications Center
of the Oak Ridge National Laboratory
Recently, I released MSP430static, a tool for reverse engineering MSP430 firmware. This article is a tutorial on the installation and usage of the tool.
As a development tool under active development, msp430static is very rarely distributed in packaged form. Just grab the latest code from subversion, like so:
Once the application is installed, it'll likely be necessary to chase prerequisites. You will need mspgcc. Run 'm4s' to see the error message, then follow the installation procedures for your operating system. The following example is from a Gentoo machine.
Before we use the tool, it might be helpful to explain the manner in which it is used. MSP430static is built as a Perl script which wraps an SQLite3 database. It is called either from the unix shell or from its own shell, and a lot of work can be performed by macros and subs. Macros are short, parameter-less blocks of code written in Perl, shell script, or SQL. Subs are SQL functions which are written in perl, but other languages will be added soon. (I'm writing this before feature-creep sets in. Check the formal documentation for whatever is new.)
The database file resides in the current working directory and is always named 430static.db. The database contains tables (code,funcs,symbols) for managing a working codebase. Other tables (lib) store library functions for symbol identification. Others (macros, subs) store macros and subroutines which extend the command language of the interpreter.
Let's begin analyzing some code. In my case, I'll begin my database with the TinyOS Blink example.
Let's try things from the other side of the fence, though. Suppose you have a firmware that you'd like to reverse engineer. How much can we determine without symbol names? A callgraph, such as this one, is easy enough to generate by the .callgraph.* macros. .callgraph.xview or .callgraph.kgv will display the graph, and my PDF was generated by the following:
Supposing I wanted to see what an attacker could determine of my application, knowing only the standard libraries but nothing of my source code, I could run the following:
It's also important to note that function inlining can make fingerprinting difficult. As TinyOS inlines functions by default, the same function might be inlined in one example and not in another. (At present, inlined functions cannot be automatically recognized.)
I haven't room here to enumerate all the features of msp430static, but luckily it will enumerate them for you. The macro .macros will list all macro names and comments. .subs will list all subroutines and comments.
In the following example, I add a new macro function which lists the functions which have not been identified in the library.
This ends the tutorial, but you should play around with the macros and subroutines further. Try writing a few of your own, and email them to me if they're interesting.
at the Extreme Measurement Communications Center
of the Oak Ridge National Laboratory
Recently, I released MSP430static, a tool for reverse engineering MSP430 firmware. This article is a tutorial on the installation and usage of the tool.
Installation
As a development tool under active development, msp430static is very rarely distributed in packaged form. Just grab the latest code from subversion, like so:
mil% svn co https://msp430static.svn.sourceforge.net/svnroot/msp430static msp430staticOnce the code has been checked out, install it like so:
mil% cd msp430static/trunkWhen installing from the trunk version, links--rather than copies--will be made. This ensures that upgrading is as simple as running 'svn update'.
mil% sudo make install
ln -s `pwd`/msp430static.pl /usr/local/bin/msp430static
ln -s `pwd`/msp430static.pl /usr/local/bin/m4s
mil%
Once the application is installed, it'll likely be necessary to chase prerequisites. You will need mspgcc. Run 'm4s' to see the error message, then follow the installation procedures for your operating system. The following example is from a Gentoo machine.
mil% m4sOnce you've chased all of the absolute prereqs, the command with no arguments should merely return. At this point, you can begin to play with the tool.
install_driver(SQLite) failed: Can't locate DBD/SQLite.pm in @INC (@INC contains: /etc/perl
/usr/lib/perl5/site_perl/5.8.6/i686-linux /usr/lib/perl5/site_perl/5.8.6 /usr/lib/perl5/site_perl
/usr/lib/perl5/vendor_perl/5.8.6/i686-linux /usr/lib/perl5/vendor_perl/5.8.6 /usr/lib/perl5/vendor_perl
/usr/lib/perl5/5.8.6/i686-linux /usr/lib/perl5/5.8.6 /usr/local/lib/site_perl .) at (eval 2) line 3.
Perhaps the DBD::SQLite perl module hasn't been fully installed,
or perhaps the capitalisation of 'SQLite' isn't right.
Available drivers: DBM, ExampleP, File, Proxy, Sponge, mysql.
at /usr/local/bin/m4s line 297
mil% sudo emerge dev-perl/DBD-SQLite
...
mil% m4s
mil%
Organization
Before we use the tool, it might be helpful to explain the manner in which it is used. MSP430static is built as a Perl script which wraps an SQLite3 database. It is called either from the unix shell or from its own shell, and a lot of work can be performed by macros and subs. Macros are short, parameter-less blocks of code written in Perl, shell script, or SQL. Subs are SQL functions which are written in perl, but other languages will be added soon. (I'm writing this before feature-creep sets in. Check the formal documentation for whatever is new.)
The database file resides in the current working directory and is always named 430static.db. The database contains tables (code,funcs,symbols) for managing a working codebase. Other tables (lib) store library functions for symbol identification. Others (macros, subs) store macros and subroutines which extend the command language of the interpreter.
Usage
Let's begin analyzing some code. In my case, I'll begin my database with the TinyOS Blink example.
mil% msp430-objdump -D /opt/tinyos-2.x/apps/Blink/build/telosb/main.exe | m4s initThis initializes the database with the dumped executable code, then calls a database summary. As this example includes symbol names, I need no library functions. Just to show off the library features, let's see which functions from libc exist here.
mil% m4s .summary
/home/travis/svn/msp430static/trunk/msp430static.pl
1000 instructions
33 functions from 1100 to 4a64
0 of 0 library functions found
73 distinct memory locations are poked.
0 lib functions.
0 unique lib function names.
0 unique lib function checksums.
mil
mil% m4s .lib.import.gnu >>/dev/nullNow that we know a function has been found, let's take a look at it.
mil% m4s .summary
/home/travis/svn/msp430static/trunk/msp430static.pl
1000 instructions
33 functions from 1100 to 4a64
1 of 2099 library functions found
73 distinct memory locations are poked.
2099 lib functions.
587 unique lib function names.
543 unique lib function checksums.
mil%
mil% m4s shellUsing the msp430static shell in the example above, the first query lists all recognized functions and their hexadecimal address. The second grabs the code of that function. The third grabs the symbol name that shipped with the executable. It's clear that this recognition is merely coincidence, Msp430TimerP$1$Event$default$fired is mistaken for __clear_cache as both perform the exact same thing: A simple return. Let's drop the GNU stuff and load only the TinyOS files.
m4s sql> .funcs.inlibs
4118 __clear_cache
m4s sql> select asm from funcs where address=dehex('4118');
4118: 30 41 ret
m4s sql> select name from funcs where address=dehex('4118');
Msp430TimerP$1$Event$default$fired
m4s sql>
mil% m4s shellThis time, many more functions are identified. If the Blink executable still remains, they ought to all be recognized. Supposing that you sell a proprietary library for the MSP430, msp430static makes it trivial to catch copyright violators. By running loading suspect firmware and calling the .funcs.inlibs macro, in seconds you can determine whether your library is being used.
m4s sql> delete from lib;
m4s sql> lib.import.tinyos
...
#887 lib functions.
#213 unique lib function names.
#213 unique lib function checksums.
m4s sql> .funcs.inlibs
403a __ctors_end
403e _unexpected_
404c __nesc_atomic_start
4060 __nesc_atomic_end
4084 Msp430TimerCapComP$0$Event$fired
4094 Msp430TimerCapComP$1$Event$fired
40a4 Msp430TimerCapComP$2$Event$fired
4118 Msp430TimerP$1$Event$default$fired
43a4 Msp430TimerP$1$Timer$get
454c Msp430ClockP$set_dco_calib
4568 MotePlatformC$TOSH_FLASH_M25P_DP_bit
4118 SchedulerBasicP$TaskBasic$default$runTask
4a62 __stop_progExec__
41da SchedulerBasicP$TaskBasic$postTask
432e TransformCounterC$0$Counter$get
473e TransformAlarmC$0$Alarm$startAt
477c AlarmToTimerC$0$fired$runTask
47c0 VirtualizeTimerC$0$Timer$startPeriodic
4986 SchedulerBasicP$TaskBasic$runTask
499e McuSleepC$getPowerState
m4s sql>
Let's try things from the other side of the fence, though. Suppose you have a firmware that you'd like to reverse engineer. How much can we determine without symbol names? A callgraph, such as this one, is easy enough to generate by the .callgraph.* macros. .callgraph.xview or .callgraph.kgv will display the graph, and my PDF was generated by the following:
karen% m4s .callgraph.ps >foo.ps
karen% ps2pdf foo.ps
karen%
Supposing I wanted to see what an attacker could determine of my application, knowing only the standard libraries but nothing of my source code, I could run the following:
karen% m4s shellThe callgraph, available here, shows that some, but not all, of the functions are identified. (In practice, the example projects ought to be completely identified. Any private functions, not imported by the script, will not be shown.)
m4s sql> update funcs set name='unknown';
m4s sql> .symbols.recover
m4s sql>
karen%
It's also important to note that function inlining can make fingerprinting difficult. As TinyOS inlines functions by default, the same function might be inlined in one example and not in another. (At present, inlined functions cannot be automatically recognized.)
Macros and Subs
I haven't room here to enumerate all the features of msp430static, but luckily it will enumerate them for you. The macro .macros will list all macro names and comments. .subs will list all subroutines and comments.
karen% m4s .macrosThese are just rows in the database, so new subs and macros may be written from SQL. The source code to a sub or macro may be called by a SELECT statement. (A few of these call functions in msp430static.pl.)
.callgraph Dump a digraph call tree for graphviz.
.callgraph.gv View a callgraph in ghostview.
.callgraph.kgv View a callgraph in kghostview.
.callgraph.lp Print callgraph for US Letter.
.callgraph.ps Postscript callgraph, sized for US Letter.
.callgraph.xview View a callgraph in xview.
.code.switches List branches belonging to jump-table switch statements.
.export.aout Dumps the project an a.out executable.
.export.ihex Dumps the project as an Intel Hex file.
.export.srec Dumps the project as a Motorolla SRec file.
.funcs.inlibs List functions which appear in libraries.
.funcs.outside List instructions where are not part of any function.
.funcs.overlap List overlapping function addresses.
.lib.import.gnu Import mspgcc libraries from /usr/local/msp430.
.lib.import.tinyos Import mspgcc libraries from /usr/local/msp430.
.macros Lists all available macros.
.memmap.gd.eog View a callgraph in Eye of Gnome.
.memmap.gd.gif Output a GIF drawing of memory.
.memmap.gd.jpeg Output a JPEG drawing of memory.
.memmap.gd.png Output a PNG drawing of memory.
.memmap.gd.xview View a callgraph in xview.
.memmap.pstricks Output a LaTeX drawing of memory.
.missing Default macro, run whenever a missing macro is called.
.subs Lists all additional SQL functions.
.summary Output a summary of the database contents.
.symbols.recover Recover symbol names from libraries.
karen% m4s .subs
addr2func Returns the starting address of the function containing the given address.
addr2funcname Returns the name of the function containing the given address.
callgraph Returns a graphviz callgraph.
dehex Converts a hex string to a numeral.
enhex Converts a numeral to a hex string.
fprint Position-invariant fingerprint of an assembly code string.
to_ihex Returns a line of code as an Intel Hex entry. [broken]
karen%
In the following example, I add a new macro function which lists the functions which have not been identified in the library.
m4s sql> select * from macros where name like '.funcs.inlibs';Macros may be written in perl, sql, or unix shellscript. Subs work similarly, but there's only perl support at the moment.
.funcs.inlibs
sql
List functions which appear in libraries.
select distinct enhex(f.address), l.name from lib l,funcs f where f.checksum=l.checksum;
m4s sql> select distinct enhex(f.address),f.name from funcs f where
f.checksum not in (select checksum from lib);
43dc unknown
411a unknown
4230 unknown
48fe unknown
4810 unknown
4580 unknown
45ce unknown
4686 unknown
4886 unknown
40b4 unknown
4068 unknown
43b8 unknown
40fa unknown
4000 unknown
m4s sql> insert into macros values('.funcs.notinlibs',
'sql',
'List functions which do not appear in libraries.',
'select distinct enhex(f.address),f.name from funcs f where
f.checksum not in (select checksum from lib);';
m4s sql> .funcs.notinlibs
43dc unknown
411a unknown
4230 unknown
48fe unknown
4810 unknown
4580 unknown
45ce unknown
4686 unknown
4886 unknown
40b4 unknown
4068 unknown
43b8 unknown
40fa unknown
4000 unknown
m4s sql>
Further Usage
This ends the tutorial, but you should play around with the macros and subroutines further. Try writing a few of your own, and email them to me if they're interesting.
Rabu, 23 Januari 2008
Static Analysis of MSP430 Firmware in Perl
by Travis Goodspeed <travis at utk.edu>
at the Extreme Measurement Communications Center
of the Oak Ridge National Laboratory
That which follows is an adaption of notes which I made during the course of writing msp430static, a sort of poor man's IDA Pro for static analysis of MSP430 firmware without source code.
In the unstripped binary, we'll find the code for strcpy at the address (0x11a4) called above:
The stripped binary has the function at the same address, but has no function label. In fact, there isn't even a note (in msp430-objdump) that the address is the beginning of a function.
Note that calling conventions vary considerably across the many MSP430 compilers and even among versions of the same compiler, depending upon optimization options and inlining. Don't expect all calls to look like this: check for yourself.
Before looking at a decompilation of the above, notice that a reasonably large string of bytes {6f 4e, cd 4f 00 00, 4f 92} appears twice. This duplicity might be removed by another optimizer, but it shows that something in the code is sufficiently intrinsic to the function to appear twice in one function. Perhaps it will remain consistent across compilers? In point of fact, this expanse of code copies a byte from the address contained within r14 to the address contained within r13. The final word compares the byte that was copied to zero. In the first usage, the function jumps to the end in the event that the comparison is zero. In the second usage, which follows the incrementing of both r14 and r15, the jump is backward if the comparison is not zero. A rough approximation in psuedo-C follows
It is apparent that this could be written a bit more compactly by merging the first and second stanzas. Also, the use of the indirect auto-increment addressing mode (As=11, of the form @Rn+) could eliminate the "inc r14" line. The instructions might also be reordered, and any number of register combinations might be used to hold intermediate values. It's not possible to detect all the ways in which strcpy() might be implemented, but it shouldn't be too difficult to detect the different ways in which it will be implemented. After all, it's far easier to fix an overflow vulnerability than to hide it; is it not?
Testing my theory, I disassembled the same program, this time compiled with IAR's compiler (V4.09A/W32). Grepping for cmp.b yielded a single line, at address 0xF86E, in the codeblock which follows.
This code is heavily--but imperfectly--optimized, so it's a bit difficult to decompile by hand. It all becomes clear when you realize that r12 is post-incremented and the original value is loaded into r14, the destination address for each character. Unlike GCC, the indirection post-increment addressing mode is used, but on the very next line we see that this necessitates another RAM access! Perhaps the cache will take care of it, but this means that IAR makes three memory accesses--one write and two reads--for every two that GCC makes. I'd recommend hand optimization for this function, if my stronger recommendation wasn't to scrap it as a troublemaker.
The decompiled code follows,
So how do we do a generalized search for this, one which will recognize most implementations by most compilers? I propose a pattern that looks for the following:
It's possible to add more rules which describe the preceding examples. For example, both of these examples move their first parameter to a temporary register and, later, move it back. Both follow the cmp.b with a jnz. I advise against making any matching pattern too strict, as it'll result in false negatives. Keeping things loose might result in false positives, but those false positives will be fertile ground for exploits of their own, even if they aren't strcpy().
It's also worth noting that a ruleset that's complex is easy to sneak by, either intentionally or accidentally. Suppose this pattern were modified to exclude strncpy(). The following strcpy() implementation would skate by, undetected.
The first step is to recognize individual lines. I used the following regular expressions in an early revision:
Once lines are recognized, they are loaded into a list of strings, indexed by the integer (not hex-string) value of the first field. I make a list of strings, rather than objects, because most comparisons can be performed by regular expressions. This is fine for a 16-bit microcontroller, but might be prohibitively expensive for something larger.
Routines are recognized--as I've previously stated--by assuming that they reside between ret statements. This assumption makes things quite easy to implement, but results in the loss of the first function as well as the concatenation of functions--such as main()--which do not return. In the following example main [118E to 11A0] and strcpy [11A4 to 11C2] are combined into a single listing:
By searching by call targets, my script correctly recognizes the second function of the preceding example, but it no longer recognizes main(), which in GCC is called by "BR #addr" and not "CALL #addr". A quick check on a small GCC program shows that absolute jumps are only used for main() and non-user functions. Thus, by looking for "CALL #addr" and "BR #addr", it is possible to find the entry points of most if not all functions.
Once functions can be been identified, it isn't very difficult to add an output mode for Graphviz. The following image is a call tree in which main() calls two functions which call strcpy(). Dangerous functions and calls are labeled in red. The two islands on the right--which prevent this from being a Tree in the graph theory sense--exist in assembly as infinite loops.
Further, it's also useful to produce memory maps which detail memory usage. These can be produces from the database by dumping to a graphics programming language. My first revision published to LaTeX/PSTricks. This looks beautiful, but rendering everything as vector art quickly makes a complex memory map unmanageable. My solution was a rewrite that prints raw postscript. Both are shown below.
My redesign will feature an SQL backend, such that the input file needn't be reparsed for each minor revision. This will also allow for scripting in languages other than perl. A single command will stock a database of a defined schema, a second will analyze the database, and others will produce output or analysis. I intend to do most analysis in a self-contained perl script, but clients may be written in a variety of languages as appropriate. I'm undecided as to whether I'll make the tool architecture-agnostic in this revision. It's possible, but perhaps that's more appropriate for a later revision. Potential clients include a modified msp430simu and a GTK# GUI.
I don't intend to make a public release of the present version, but I'll send individual copies by email upon request.
at the Extreme Measurement Communications Center
of the Oak Ridge National Laboratory
That which follows is an adaption of notes which I made during the course of writing msp430static, a sort of poor man's IDA Pro for static analysis of MSP430 firmware without source code.
What Functions Look Like
A call to strcpy, such as the one which follows, is accomplished by populating r15 with the destination address and r14 with the source address, then calling the function at its hex address. In the following example, foo is the target (r15) and babe is the source (r14). See my article on IAR's MSP430 calling conventions for references to calling convention documentation for various compilers, as each compiler seems to do something different on this platform.strcpy(foo,babe);
1154: 3e 40 7a 02 mov #634, r14 ;#0x027a
1158: 0f 44 mov r4, r15 ;
115a: b0 12 a4 11 call #4516 ;#0x11a4
In the unstripped binary, we'll find the code for strcpy at the address (0x11a4) called above:
000011a4 <strcpy>:
11a4: 0d 4f mov r15, r13 ;
11a6: 0c 4f mov r15, r12 ;
11a8: 6f 4e mov.b @r14, r15 ;
11aa: cd 4f 00 00 mov.b r15, 0(r13) ;
11ae: 4f 93 cmp.b #0, r15 ;r3 As==00
11b0: 07 24 jz $+16 ;abs 0x11c0
11b2: 1e 53 inc r14 ;
11b4: 1d 53 inc r13 ;
11b6: 6f 4e mov.b @r14, r15 ;
11b8: cd 4f 00 00 mov.b r15, 0(r13) ;
11bc: 4f 93 cmp.b #0, r15 ;r3 As==00
11be: f9 23 jnz $-12 ;abs 0x11b2
11c0: 0f 4c mov r12, r15 ;
11c2: 30 41 ret
The stripped binary has the function at the same address, but has no function label. In fact, there isn't even a note (in msp430-objdump) that the address is the beginning of a function.
11a4: 0d 4f mov r15, r13 ;It's easy enough to detect the presence of this code in a stripped executable by looking for "mov r15, r12" or "0x0c 0xf4" and comparing the bytes that follow. I can't stress enough the importance of endian-awareness: the second column is composed of bytes, not words. As a word, "mov r15,r12" is 0xf40c. When in doubt, double-check yourself with the Single Line MSP430 Assembler.
11a6: 0c 4f mov r15, r12 ;
11a8: 6f 4e mov.b @r14, r15 ;
11aa: cd 4f 00 00 mov.b r15, 0(r13) ;
11ae: 4f 93 cmp.b #0, r15 ;r3 As==00
11b0: 07 24 jz $+16 ;abs 0x11c0
11b2: 1e 53 inc r14 ;
11b4: 1d 53 inc r13 ;
11b6: 6f 4e mov.b @r14, r15 ;
11b8: cd 4f 00 00 mov.b r15, 0(r13) ;
11bc: 4f 93 cmp.b #0, r15 ;r3 As==00
11be: f9 23 jnz $-12 ;abs 0x11b2
11c0: 0f 4c mov r12, r15 ;
11c2: 30 41 ret
Note that calling conventions vary considerably across the many MSP430 compilers and even among versions of the same compiler, depending upon optimization options and inlining. Don't expect all calls to look like this: check for yourself.
Before looking at a decompilation of the above, notice that a reasonably large string of bytes {6f 4e, cd 4f 00 00, 4f 92} appears twice. This duplicity might be removed by another optimizer, but it shows that something in the code is sufficiently intrinsic to the function to appear twice in one function. Perhaps it will remain consistent across compilers? In point of fact, this expanse of code copies a byte from the address contained within r14 to the address contained within r13. The final word compares the byte that was copied to zero. In the first usage, the function jumps to the end in the event that the comparison is zero. In the second usage, which follows the incrementing of both r14 and r15, the jump is backward if the comparison is not zero. A rough approximation in psuedo-C follows
char* strcpy(char* dest, char* src){In the decompilation, I refer to r15 as both dest and c, as its purpose changes completely. Variables are passed as dest=r15 and src=r14, as GCC allocates parameters in the order r15, r14, r13, r12. The result, for strcpy() the destination address, is returned in r15.
a=dest; //mov r15, r13
b=dest; //mov r15, r12
c=*src; //mov.b @r14, r15
*a=c; //mov.b r15, 0(r13)
if(c==0) //cmp.b #0, r15
goto ret; //jz $+16
do{
src++; //inc r14
a++; //inc r13
c=*src; //mov.b @r14, r15
*a=c; //mov.b r15, 0(r13)
}while(c!=0) //cmp.b #0, r15
// jnz #-12
ret:
return b; //mov r12, r15
} //ret
It is apparent that this could be written a bit more compactly by merging the first and second stanzas. Also, the use of the indirect auto-increment addressing mode (As=11, of the form @Rn+) could eliminate the "inc r14" line. The instructions might also be reordered, and any number of register combinations might be used to hold intermediate values. It's not possible to detect all the ways in which strcpy() might be implemented, but it shouldn't be too difficult to detect the different ways in which it will be implemented. After all, it's far easier to fix an overflow vulnerability than to hide it; is it not?
Testing my theory, I disassembled the same program, this time compiled with IAR's compiler (V4.09A/W32). Grepping for cmp.b yielded a single line, at address 0xF86E, in the codeblock which follows.
f864: 0f 4c mov r12, r15 ;Those that have read my article on the register usage of IAR will note that the ABI is different in the code sample above. IAR fixed the register allocation order in October of 2007, and it now allocates registers in the order r12, r13, r14, r15.
f866: 0e 4c mov r12, r14 ;
f868: 1c 53 inc r12 ;
f86a: fe 4d 00 00 mov.b @r13+, 0(r14) ;
f86e: ce 93 00 00 cmp.b #0, 0(r14) ;r3 As==00
f872: f9 23 jnz $-12 ;abs 0xf866
f874: 0c 4f mov r15, r12 ;
f876: 30 41 ret
This code is heavily--but imperfectly--optimized, so it's a bit difficult to decompile by hand. It all becomes clear when you realize that r12 is post-incremented and the original value is loaded into r14, the destination address for each character. Unlike GCC, the indirection post-increment addressing mode is used, but on the very next line we see that this necessitates another RAM access! Perhaps the cache will take care of it, but this means that IAR makes three memory accesses--one write and two reads--for every two that GCC makes. I'd recommend hand optimization for this function, if my stronger recommendation wasn't to scrap it as a troublemaker.
The decompiled code follows,
char* strcpy(char* dest, char* src){I'd be willing to bet that the original is quite a bit denser in C, but this ought to be easy enough to understand.
char *a,
*b=dest; //mov r12, r15
do{
a=dest; //mov r12, r14
dest++; //inc r12
*(a++)=*src; //mov.b @r13+, 0(r14)
}while(0!=*src); //cmp #0, 0(r14)
//jnz $-12
return b; //mov r15, r12
//ret
}
So how do we do a generalized search for this, one which will recognize most implementations by most compilers? I propose a pattern that looks for the following:
- The use of two registers, source pointer SRC and destination pointer DEST.
- A mov.b instruction with SRC as the source. (Call the destination FOO)
- A mov.b instruction with DEST as the destination. (Call the source BAR.)
- A cmp.b instruction involving the immediate zero and the register SRC, DEST, FOO, or BAR.
It's possible to add more rules which describe the preceding examples. For example, both of these examples move their first parameter to a temporary register and, later, move it back. Both follow the cmp.b with a jnz. I advise against making any matching pattern too strict, as it'll result in false negatives. Keeping things loose might result in false positives, but those false positives will be fertile ground for exploits of their own, even if they aren't strcpy().
It's also worth noting that a ruleset that's complex is easy to sneak by, either intentionally or accidentally. Suppose this pattern were modified to exclude strncpy(). The following strcpy() implementation would skate by, undetected.
char *strcpy(char *dest, char *src){By keeping rules loose--but perhaps prioritized--it's easy to catch such actions. After all, what byte-wise copying until reaching zero is not suspicious?
return strncpy(dest,src,0x1000);
}
Recognizing Functions from Perl
Now that the hand analysis is complete, it's time to bring perl into the mix. Instructions are recognized as one of two types: code and IVT entries. I ignore the .data section for now, but a little tweaking of the regular expressions would make it match. I make the assumption that every function begins after a 'ret' and ends with a 'ret'. This isn't strictly true, but it suffices for this article and ought only to miss the first function in memory, assuming everything is built with C.The first step is to recognize individual lines. I used the following regular expressions in an early revision:
Match an instruction:Although I don't strictly need to parse so much detail to recognize strcpy(), it will be helpful when I add features.
# 11b6: 6f 4e mov.b @r14, r15 ;
# 11b8: cd 4f 00 00 mov.b r15, 0(r13) ;
# 1111: 22222222222 33333 44444444444444 555555
/\s(....):\s(.. .. .. ..)\s\t([^ \t]{2,5})\s(.*);?(.*)/
Match an IVT entry:
# fffe: 00 11 interrupt service routine at 0x1100
/[\s\t]*(....):[\s\t]*(.. ..)[\s\t]*interrupt service routine at 0x(....)/
Once lines are recognized, they are loaded into a list of strings, indexed by the integer (not hex-string) value of the first field. I make a list of strings, rather than objects, because most comparisons can be performed by regular expressions. This is fine for a 16-bit microcontroller, but might be prohibitively expensive for something larger.
Routines are recognized--as I've previously stated--by assuming that they reside between ret statements. This assumption makes things quite easy to implement, but results in the loss of the first function as well as the concatenation of functions--such as main()--which do not return. In the following example main [118E to 11A0] and strcpy [11A4 to 11C2] are combined into a single listing:
118e: 31 40 00 0a mov #2560, r1 ;#0x0a00This happens because main() returns not by "ret" but by branching to 0x11C4, which is __stop_progExec__ in the firmware being analyzed. An alternate method would be to look for call targets, assuming that 0x11A4 is the beginning of a function because some other instruction calls it.
1192: 04 41 mov r1, r4 ;
1194: 92 43 00 02 mov #1, &0x0200 ;r3 As==01
1198: b0 12 40 11 call #4416 ;#0x1140
119c: b0 12 68 11 call #4456 ;#0x1168
11a0: 30 40 c4 11 br #0x11c4 ;
11a4: 0d 4f mov r15, r13 ;
11a6: 0c 4f mov r15, r12 ;
11a8: 6f 4e mov.b @r14, r15 ;
11aa: cd 4f 00 00 mov.b r15, 0(r13) ;
11ae: 4f 93 cmp.b #0, r15 ;r3 As==00
11b0: 07 24 jz $+16 ;abs 0x11c0
11b2: 1e 53 inc r14 ;
11b4: 1d 53 inc r13 ;
11b6: 6f 4e mov.b @r14, r15 ;
11b8: cd 4f 00 00 mov.b r15, 0(r13) ;
11bc: 4f 93 cmp.b #0, r15 ;r3 As==00
11be: f9 23 jnz $-12 ;abs 0x11b2
11c0: 0f 4c mov r12, r15 ;
11c2: 30 41 ret
By searching by call targets, my script correctly recognizes the second function of the preceding example, but it no longer recognizes main(), which in GCC is called by "BR #addr" and not "CALL #addr". A quick check on a small GCC program shows that absolute jumps are only used for main() and non-user functions. Thus, by looking for "CALL #addr" and "BR #addr", it is possible to find the entry points of most if not all functions.
Once functions can be been identified, it isn't very difficult to add an output mode for Graphviz. The following image is a call tree in which main() calls two functions which call strcpy(). Dangerous functions and calls are labeled in red. The two islands on the right--which prevent this from being a Tree in the graph theory sense--exist in assembly as infinite loops.
Further, it's also useful to produce memory maps which detail memory usage. These can be produces from the database by dumping to a graphics programming language. My first revision published to LaTeX/PSTricks. This looks beautiful, but rendering everything as vector art quickly makes a complex memory map unmanageable. My solution was a rewrite that prints raw postscript. Both are shown below.
Conclusion
I've named the tool msp430static, and I intend to publish a revision as soon as I clean up the code. It's a decent hack at this point, but a hack isn't maintainable and I shudder to think at how I'll comprehend these few hundred lines of perl in three months' time without mush revision.My redesign will feature an SQL backend, such that the input file needn't be reparsed for each minor revision. This will also allow for scripting in languages other than perl. A single command will stock a database of a defined schema, a second will analyze the database, and others will produce output or analysis. I intend to do most analysis in a self-contained perl script, but clients may be written in a variety of languages as appropriate. I'm undecided as to whether I'll make the tool architecture-agnostic in this revision. It's possible, but perhaps that's more appropriate for a later revision. Potential clients include a modified msp430simu and a GTK# GUI.
I don't intend to make a public release of the present version, but I'll send individual copies by email upon request.
Langganan:
Postingan (Atom)
Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor
Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor Halo, para pecinta judi online! Apakah Anda sedang mencari car...
-
I'm able to’t tell you numerous girls have instructed maine over time and months that they may be in an awful book club oregon desires ...
-
Meraih Jackpot Besar: Strategi dan Tips Bermain Slot dengan Agen Slot Gacor Halo, para pecinta judi online! Apakah Anda sedang mencari car...
-
College football is an actual thrilling overall performance. Nan rating isn't always constant while you're looking astatine footbal...