rdist

July 3, 2008

Dead-listing while on vacation

Filed under: Embedded,Reverse engineering,Security — Nate Lawson @ 10:21 pm

I just got back from a nice vacation with no laptop.  What do I do on long plane rides or while listening to the waves lap against the beach?  Dead-listing.

Dead-listing is analyzing the raw disassembly of some target software and figuring it out using only pen and paper.  This is great for vacations because your laptop won’t get sand in it.  You usually have a long period of time to muse about the code in question without interruptions, something hard to find at home these days.  And I’ve gotten some of my best ideas after setting aside my papers for a while and going for a long swim.

Before you leave, pick an interesting target: not too big, not too small.  Not just x86 either — ever wondered how one of your cellphone’s applications worked?  Never looked at a familiar application’s Java bytecode?  Then, get a copy of a disassembler for your target and run it.  I often use IDA but for less common CPU architectures, any one will do.  Remember that you don’t need full analysis at this point, although it’s useful to be able to separate data from instructions and get basic symbols resolved.

Search the assembly code for any external libraries that might be important.  Disassemble them too.  While you’re at it, see if you can find the source code or API reference for any of those files.  Code reuse helps you reduce the amount you have to reverse yourself.

Now take the listing file and do some cleanup.  I like to use a small font that prints well and convert all the call (subroutine) instructions to bold.  I insert some extra empty lines before each call target to allow me room to write notes.  Finally, I print the listing in landscape with two columns per page.  This leaves room for notes on the righthand side of each column and some at the bottom.  A binder clip makes it easy to keep pages in order or remove them to compare.

Since you won’t have access to the Internet, you’ll need to find some basic reference materials.  The key is to get the basics without carrying a ream of paper.  For an embedded system, I usually find or make a small instruction set reference sheet including status flags, I/O port table, PCB layout photos, and any integrated peripherals I find during a brief search of the data accesses.  Print these out and put a full copy of all the files on a USB flash drive.  You might stop by an Internet cafe if you find you really need to read a missing page.  I’ve never found that necessary though.  If I can’t infer the function of a particular I/O access, I’ll just look at the whole block’s general effect and take a guess.

The most important part is to stay light.  You don’t need exhaustive manuals (e.g., instruction timing).  Instead, treat these barriers as a challenge.  For example, most timing loops are relative to each other.  You can figure out that one loop is twice as slow as the other without knowing its exact delay in nanoseconds.  Doing hexadecimal conversions on paper builds character.

Once you’re away, enjoy doing a little bit at a time.  I’d often work through a subroutine or lay out a switch statement over coffee before the family gets moving, then set it aside for the rest of the day.  Before putting it down, keep a separate log of open questions and tasks, marking them off as you solve them.  I usually reserve a page in this notebook as my “symbol table”, marking down function names/addresses as I finalize them.

I mostly work through the code in two modes: looking for high level blocks or walking through a single subroutine in detail.  Was this compiled C or C++?  How does the optimizer work?  When accessing hardware, where did the author use inline assembly?  Draw arrows, bracket blocks, use highlighters if that’s your style.  Since it’s more free-form than working on a computer, you’ll find new ways to annotate it.  The amount of marks per page gives a good idea as to code coverage so you can start a day by refining an existing page or try to take a broad guess what a blank page does.

I am always surprised how much I accomplish in only a little bit of time using this method.  It’s also so much fun.  Throw in reading a few interesting but unrelated books and you may wax philosophical on the meaning of life or why the compiler suddenly switched to byte instead of word operations for a single function.

I hope you have a great summer.  Be sure to stop by my Blackhat 2008 talk, “Highway to Hell: Hacking Toll Systems“.  I’ll be posting more details about it here in the coming weeks.

5 Comments

  1. Thoroughly enjoyed this post. I am going on vacation soon so good timing as well.

    However I prefer to stay in source code so I suspect that there will be no Dead-listing on my vacation :-)

    Favorite quote: “Doing hexadecimal conversions on paper builds character”

    Comment by David Kaspar — July 4, 2008 @ 2:13 am

  2. Hi Nate. I really enjoyed reading this post. I never realized reading assembly code could be so thrilling. :-)
    I also find your quote about hexadecimal conversions by hand interesting. Most students nowadays don’t understand the value of programming in paper and knowing how the bases work. So, let me tell you a story. :-) When I was younger my parents forbidden me to use the computer for any task because my grades were low. I wasn’t actually playing games at the time, but learning to program in C. I was so frustrated that I couldn’t use the computer that I started writing code in a piece of paper. They didn’t bother because I think they though I was studying, ;-). At first, it all seemed wrong, but I soon realized I was much more concentrated than if I was in front of the computer.

    I wish I could, but I can’t attend Blackhat 2008. Good luck with your talk!
    Have a nice summer!

    Comment by Rui Paulo — July 5, 2008 @ 8:17 am

  3. Thanks, I enjoyed writing a more lighthearted post. I’ve written a lot of code on paper, starting from 6502 asm for a joystick handling routine in the back leaf of a textbook.

    I think paper is a great way to write some kinds of routines or outline a new algorithm. So much so that I include a written programming question in all interviews I perform. It’s a great balancer to verbal questions since you can leave the coder alone to concentrate. Also, you get to see their mistakes and rejected attempts along the way which gives good insight into thought processes.

    Comment by Nate Lawson — July 5, 2008 @ 6:54 pm

  4. It wasn’t strictly dead-listing, since I was also able to use an assembly-level debugger to check things out, but years ago I had the job of reverse-engineering the newest release of the Avid video-editing suite so we could get around their attempts to restrict usage to only their own branded storage systems. We were doing our own high-performance Fibre Channel shared storage marketed primarily to film/video houses, so it was critical that we could work with the Avid stuff. It was a intense week or so of nothing but tracing and disaassembly, and I’ve still got my binder-clipped stack of I don’t know how many pages of raw assembly code covered in my notes and conjectures and hand-decompilations. It was a blast…completely took me back to trying to crack games and beef up my Ultima stats and such in the old Apple II days.

    Comment by Grimtooth — July 10, 2008 @ 3:11 pm

  5. its interesting noting the tasks where printouts are much better than computers. i find it usually breaks down to annotation; if i need to mark something up a printout is usually the only way.

    Comment by web design — July 11, 2008 @ 7:10 am


RSS feed for comments on this post.

Blog at WordPress.com.