Author: Godfrey Nolan
Audience: Android developers
Reviewer: Mike James
Is your code at risk from decompilation? Of course it is, and as a result you should have some interest in finding out about how to decompile Android code.
This book is about a topic that generally doesn't get much coverage, mainly because it is difficult to write about. Decompiling is what you do when you need to discover what the original code was. You take some machine code or some intermediate code and put it through a decompiler to see the original source code - or as close to the original souce code as you can get.
Why would you want to do this?
There are many reasons but most of the time it is because you want to discover how the original program works. Perhaps you just want to know out of curiosity, but most of the time the reason is usually that you want to create a modified version of the program. Yes, decompiling is usually about stealing someone's idea or more precisely someone's app. This gives it a slightly grubby feel to the activity, discussing the activity and of course any book on the subject.
The usual defense of any book on hacking or decompiling is to point out that by knowing your enemy you can protect yourself. This is probably true. A more important reason for reading such books, however, is that at they usually represent the lowest level of knowledge about how things work.
In books such as this one you can find lots of information that generally is regarded as too difficult for books on mainstream topics. In other words, by reading about decompiling Android you can potentially learn a lot of deep technical things about the Android system.
This book starts off with a waffly look at the idea of decompiling and it makes the point that Java, which is what most Android code is written in, is very easy to decompile. The reason it is easy is because the intermediate code that is fed to the JVM contains a lot of information about the source code. Of course, this chapter also points out the legal side of decompiling code, some of the history and "moral issues".
If you know anything much about Java or programming you might also find the tone of the book strange. It introduces fairly simple ideas as if they were rocket science. I suppose that some readers might find the ideas expressed new or strange but if so they aren't going to cope with understanding a disassembly of a real program.
Chapter 2 is a nice, gentle introduction to the JVM. It explains how it works and what is inside a class file. Some of this is very long and drawn out with lots of file dumps that could have been heavily edited down. Basically, what we are talking about is a syntax diagram for the structure of a class file.
Chapter 3 repeats the task for the Android DEX file. Of course the problem with Android is that it isn't pure Java. The Java bytecode is recompiled into Dalvik bytecode which makes the jobe of decompiling it different from decompiling Java bytecode. Fortunately there are tools that convert Dalvik bytecode into Java bytecode and this does make the problem more or less the same.
Chapter 4 gives a list of tools that you can use to do the decompiling of the Dalvik bytecode. It closes with a look at obfuscation which is really the only protection you have against decompiling. This is in many ways the most practically useful part of the book in that it saves you having to do the research to find out what tools are available.
Chapters 5 and 6 are on the theory and practice of decompiler design, which is a fairly esoteric subject. Most people just want to use a decompiler to convert bytecode into source code. If you are interested in building your own decompiler then you might get something from these two chapters - but they are not deep.
The final chapter is a case study of obfuscation. This is basically a look at two possible obfuscation tools, how to use them and how well they work.
There is some useful information in this book but there is also a lot of wasted space. Very long listings of essentially tedious data and code uses up a lot of space. There is also a lot of discussion of the fairly obvious and a general feeling that the subject is being treated in a fairly superficial way.
The author makes a point of emphasizing that this is a practical approach to decompiling. This is mostly true but even here he avoids discussing the real difficulties of working with a decompile of a large program. It is hard enough to understand a large program when you have the original source code in front of you. Doing the same job with a decompiled imperfect source code is even harder and there are many techniques that you can use to try and make the task easier. This is the difficult part of decompilation and this book really doesn't go into it. It also really doesn't deal with the subject of creating a good decompiler which need much more theory than is supplied.
This is a fairly superficial look at decompiling but it might be all you need to understand the ideas and the threat it poses to your code.