All
third-party applications written for the BlackBerry must be written in
Java or use one of RIM’s alternate application development runtimes. The
universal use of managed runtimes sacrifices a small amount of speed in
favor of reducing the device’s attack surface and increasing developer
productivity.
In addition to the Java
application runtime, there is the MDS runtime. MDS applications are
built using a Visual Studio plug-in, a data-driven presentation
language, JavaScript, and specially written web services. Enterprises
develop MDS applications to interact with backend systems, such as their
inventory or sales systems.
Coding Environment
RIM provides two free Java
IDEs: the BlackBerry Java Development Environment (JDE) and the
BlackBerry JDE plug-in for Eclipse. The choice of toolset comes down to
developer preference because both are similar and freely downloadable
from RIM (http://na.blackberry.com/eng/developers/javaappdev/devtools.jsp).
For those that abhor GUIs, or have an automated build environment, a
command-line toolset is available. For all tools, free registration may
be required. The toolset works best on Windows, with some tools not
working completely or at all on other operating systems. Some
enterprising hackers have reported success running under a Windows
emulator such as WINE.
The Java development
environments include all of the tools and simulators needed to develop
and test BlackBerry Java applications. Prior to each BlackBerry OS
release, the JDE is updated with new simulators, libraries, and
documentation.
From
within the JDE or the Eclipse plug-in, you can select the OS version to
target, build applications, deploy to the simulator, and debug
application code. For more information on configuring and installing the
JDE, see RIM’s developer documentation. Applications targeted for older
versions of the JDE will still run on newer devices, so developers
typically build with the first version of the JDE that includes all of
the features they need.
Note
When
you’re writing a BlackBerry application in Eclipse, the project must be
“Activated for BlackBerry.” This can be done by right-clicking on the
project in the Package Explorer and verifying that the Activated for
BlackBerry option is enabled. This may be the root cause of a project
refusing to deploy to a device and is directly to blame for this
author’s hair loss.
Java code compiled for the BlackBerry goes through the following steps using the tools mentioned:
Code
is compiled using the javac.exe compiler, and an application JAR file
is generated. At this point, all Java methods, constructs, and classes
are fair game.
The
preverify.exe tool is run against the generated JAR files and looks for
code constructs that are not allowed in JME applications (for example,
calls to Java native invocation or invalid Java instructions). The
pre-verifier is used in both BlackBerry and JME development. Once the
pre-verifier step completes, the classes are marked as verified.
RIM’s
compiler, rapc.exe, converts the verified JAR file to a BlackBerry
executable COD file. Rapc is an optimizing compiler that removes
symbolic information and adds RIM proprietary instructions to the binary
in order to reduce size and improve performance.
If
the application is going to be deployed to a real device or to a
simulator with security enabled, the COD file is signed using the RIM
Signature Tool and the developer’s signing keys. For more details on
BlackBerry code signing, see the section titled “Permissions and User
Controls.”
Simulator
The RIM BlackBerry simulator
(a.k.a. fledge.exe) emulates all BlackBerry functionality.
Convienently, the simulator and images are bundled with both the Eclipse
plug-in and the JDE or are downloadable as a separate package. The
simulator natively supports GPS emulation, cellular calls, holstering, and anything else that one would want to do with a BlackBerry.
By default, the BlackBerry
simulator files are installed and bundled along with the JDE. To launch
the simulator from Eclipse, create a BlackBerry project in the
development environment, write the application’s code, and then run the
DebugServer profile by clicking on the “play” icon in the toolbar.
Eclipse will automatically push the compiled application to the
simulator, and it will be available on the Applications screen. If there
are any errors, the application will not be loaded and the icon will
not show up in the BlackBerry’s Applications menu.
To control the behavior
of the simulator, select and configure the Run profile within Eclipse or
the JDE. Simulator options are on the Simulator tab of the Run profile
and are divided into even more options. The following options are the
most relevant when you’re performing security testing:
Simulator tab | General tab | Enable Device Security
By default, the simulator does not enforce device security
requirements. Enabling this option will cause the BlackBerry simulator
to enforce signature checks and cause the security subsystem to behave
like an actual device.
Simulator tab | General tab | Launch Mobile Data System Connection Service (MDS-CS) with Simulator
Unless the device is configured for direct Internet access, MDS is
required to browse the web and make network connections. For simple
application testing, it is easiest to launch the MDS-CS emulator, which
proxies emulator network traffic through the PC’s network connection.
When doing security
testing, create one simulator profile with device security enabled and
one without. This makes it easier to toggle between the two modes to
learn more about how the BlackBerry device’s security system works.
Debugging
Debugging live code is a
great way to learn about application and operating system internals.
Thankfully, both Eclipse and the JDE include a debugger for runtime
analysis of BlackBerry Java applications running in either the simulator
or on an actual device. To launch custom application code in either
environment, click the Debug button on the toolbar. The IDE will launch
the simulator, deploy the application, and connect the debugger. After
the application is launched, any breakpoints or unhandled exceptions
will cause the debugger to break, thus providing you an opportunity to
inspect or modify variables and to control execution.
To debug
applications on a live BlackBerry device, connect the device to the
computer using a USB cable. Within the IDE, select the BlackBerry Device
profile. If the device is not automatically detected, open up the
property pages and ensure that the appropriate BlackBerry device is
associated with this debug profile. To do this, open the debug profile’s
property page and click the BlackBerry Device tab. Select the
appropriate device from the dropdown list. Remember that all real-world
BlackBerry devices enforce code signing, and applications that access
privileged APIs will be blocked from running unless they are signed.
Eclipse and the JDE do not allow
debugging of applications without source code or “.debug” symbol files.
When an exception occurs in a program without debug information, the
IDE will display an error. The IDE will not display any disassembly
because it is not capable of disassembling the BlackBerry JVM’s
proprietary instructions. Despite this limitation, the debugger is a
valuable reverse engineering tool for figuring out how the BlackBerry OS
works.
For example, create an
application which accesses contact information through the
javax.microedition.pim.ContactList JME class. Build the application,
skip signing, and deploy it on a security-enabled simulator with the
debugger attached. The BlackBerry will display a prompt asking if the
application should be granted permissions to access personal data. Deny
this prompt and a JVM security exception will occur and cause the
debugger to break. Here is where it gets interesting; the debugger will
show the following stack trace in the Thread information window:
MIDletSecurity.checkPermission(int, boolean, boolean, boolean,
String) line: 518
MIDletSecurity.checkPermission(int) line: 382
PIMImpl.openPIMList(int, int) line: 80
ContactTestScreen.OpenContactItem() line: 112
ContactTestApp.<init>() line: 66
ContactTestApp.main(String[]) line: 49
This experiment reveals
several details about what is going on under the covers. First,
PIMImpl.openPIMList is the class actually implementing the ContactList
functionality. Second, the MIDletSecurity class performs the security
check upon object open and not at application startup. Last of all, the
names of the internal security classes are revealed, and we know where
to look to find out more about the permission system.
Note
The
behavior for MIDP2 and RIM Controlled classes is different. Unsigned
applications that use RIM Controlled classes will fail to load and a
security message will be displayed to the user. More information is
provided in the section “Permissions and User Controls.”
Disassembly
The
BlackBerry JVM uses an extended JME instruction set and a custom
package format called a COD file. To make reversing more difficult and
improve performance, RIM’s compiler removes debug information and
collapses member names when compiling code. The custom instruction set
and executable file format are not officially documented, and what is
known is spread across the Internet in various blog posts and message
boards. All these hurdles make things look pretty rough to the aspiring
BlackBerry engineer.
Thankfully, some members
of the reverse-engineering community have released information about
COD files and some tools to disassemble BlackBerry applications. Most
notable are Dr. Bolsen for his coddec tool and Stephen Lawler for
updates and instructions. Coddec will do a half decompile/half
disassemble on BlackBerry COD files. The disassembly is actually created
by modified versions of classes that were decompiled from RIM’s rapc
compiler.
Unfortunately, coddec does
not come with much documentation, and getting it to build can be
slightly challenging. To build and run the tool, follow these
instructions, which are based on Stephen Lawler’s work:
Install
the Java Development Kit (JDK); these instructions are tested with JDK
1.6.0 R13. Also install the BlackBerry JDE, because coddec uses it in
its disassembly.
Apply the patch using the GNU patch command or TortoiseMerge.
The patch has one mistake in it, so manually change the code
c c1 = new c(l, j, i1, dataoutputstream1);
in \net\rim\tools\compiler\exec\c.java to the following:
c_static c1 = new c_static(l, j, i1, dataoutputstream1);
Copy
net_rim_api.jar from \Program Files\Research In Motion\BlackBerry JDE
4.7.0\lib to the c:\coddec directory. This file contains APIs that will
be referenced by coddec.
Collect a list of files by running the following command in the c:\coddec directory:
dir /s /b *.java > files.txt
Run the following command from a Windows command prompt that has the Java compiler in the path:
for /f %x in (files.txt) do
(javac.exe -Xlint:unchecked -cp .\;c:\coddec %x)
This command compiles all of the files. There will be lots of warnings (about 100) but there should be no errors.
Run coddec from the command prompt in the c:\coddec directory by typing java -cp . net.rim.tools.compiler.Compiler HelloWorld.cod. HelloWorld.cod is the name of the COD file to be decompiled.
The results will be output into the c:\coddec\decompiled directory.
Coddec’s output is a
combination of decompilation and disassembly of files. Consider the
following sample source code (of a thread function that should only be
written by those testing threads):
public void run() {
while(true) {
try {
Thread.sleep(3000);
if (dier == 1) { return; }
} catch (InterruptedException e) { }
}
}
Coddec is able to
reconstruct the following listing from the COD file. )
//Notice that the method name has been recovered.
public final run(com.rim.samples.device.helloworlddemo.PrimeThread);
{
enter_narrow
//Top of the while loop
Label1:
sipush 3000
i2l
//Invoke the Thread.sleep function
invokestatic_lib sleep(long) // Thread
aload_0_getfield dier
iconst_1
//Compare the "dier" field to constant 1
if_icmpne Label1
return
astore_1
goto Label1
}
This
disassembly will certainly not win a beauty competition, but it is
definitely an improvement over raw binary in COD files and is usable for
reversing applications. The decompiler and custom patching can also be
used to further explore the OS using the simulator—for example,
decompiling some of the network classes, changing their behavior,
recompiling, and then substituting the modified Java class in the
original JAR. The modified code can now be run in the simulator. This
trick will not work on real devices because they enforce code signing
for OS code.
As a final note, individual COD
files have a maximum size of 64KB. When a file exceeds this maximum, the
rapc compiler will break the file apart, append a piece number to the
filename (for example, HelloWorld-1.COD, HelloWorld-2.COD), and create a
new COD file containing the parts. These generated COD files are
actually ZIP files in disguise and can easily be recognized by the “PK”
marker in the first few bytes of the file. To decompile these files,
change the file extension to .zip, open the file in an archive manager,
and extract the individual parts. There is no obvious method to how
classes are divided between COD file parts, and each part must be
decompiled manually.
Code Security
Only the BlackBerry JVM and
lowest-level firmware are written in native code (C/C++, ASM), which
eliminates a large portion of the BlackBerry’s attack surface that may
be vulnerable to buffer overflows and other memory corruption issues.
This is proven by the fact that there are no publicly reported
BlackBerry memory corruption vulnerabilities—an impressive track record
for any device manufacturer.
To stop buffer overflows
and control the behavior of BlackBerry Java applications, RIM disallows
Java native invocation (JNI) and Java reflection. JNI allows Java code
to bridge to native C/C++ code, and allowing its use would enable Java
applications to access unintended functionality or corrupt memory. Java
reflection can be used to circumvent the public/private access
restrictions on Java classes, and its use could allow applications to
invoke internal system methods. Disabling both of these Java features is
standard for JME devices.
Application Packaging and Distribution
BlackBerry
applications can be installed via desktop connection, BlackBerry
browser, BlackBerry Desktop Manager, and BES. How applications are
packaged depends on the installation method. Each installation method
requires a code file (in the form of a COD or JAR) and a manifest
(either ALX or JAD). The manifest contains information about the
application, and the code file contains the actual application code
itself.
More information about
deploying applications and the various packaging methods is included in
the How to Deploy and Distribute Applications Guide (found at http://na.blackberry.com/developers/resources/A70_How_to_Deploy_and_Distribute_Applications_V1.pdf).
Over-The-Air (OTA) BlackBerry Browser Installation
Applications can be
installed via an application distribution point directly using the
BlackBerry browser. To do this, create a Java Application Description
(JAD) file and place the file on your web server. The JAD file contains
metadata about the application, including the vendor and application
names as well as where to download the actual binary files from. When
the user browses to the JAD file, they will see a screen similar to the
one shown in Figure 1.
The application’s signature is
verified and the application is then installed onto the BlackBerry. The
signature contained within the COD or JAR file ensures application
integrity and makes it safe to download the application over HTTP.
Before installation, the user is presented with a dialog where they can
edit security permissions and set the proper security policy for the
application.
Interestingly, the
BlackBerry does not execute the JAR files directly. Instead, the MDS
transparently transcodes the JAR into a COD file while it is being
downloaded. The MDS is careful to include all security information, and
the data is integrity-protected by the MDS-to-BlackBerry encrypted
tunnel. The MIDP specification allows this scenario explicitly.
BlackBerry Desktop Manager
Like most smartphone
platforms, the BlackBerry has special software that can be used to
manage it from the desktop. RIM’s version is the BlackBerry Desktop
Manager (BDM), which includes modules for backing up and transferring
data between devices and for installing packaged applications.
BDM
requires an .alx XML manifest file in order to install applications.
The ALX file describes the application, including vendor, dependencies,
and which COD files actually make up the application. Any code
signatures are not applied to ALX files because the signature is
contained within the associated COD file. To generate ALX files by using
the JDE or Eclipse plug-in, right-click on the application’s project
and select Generate ALX File.
BlackBerry Application Web Loader
The
BlackBerry Application Web Loader is a non-SiteLocked ActiveX control
for installing applications from a web page to devices connected to the
computer. This control has been one of the dark spots on RIM’s security
record, with a stack-based overflow reported in February 2009 that could
be used to compromise systems with the control installed. The advantage
of the Application Web Loader is that users are not required to install
BDM. For some people this is valuable enough; others may question the
wisdom of having the web push applications to one’s phone.
Note
SiteLock
is a Microsoft technology that restricts the sites allowed to load a
particular ActiveX control. Non-SiteLocked controls may be loaded by any
website, including malicious ones.
To deploy applications using
the Application Web Loader, create a JAD file and place the JAD and COD
file on an accessible web server. Then create a web page that uses the
Application Web Loader page. The BlackBerry must be attached to the
computer via a USB connection.
BES Installation
BES administrators
can manage applications, application updates, and policy to associated
devices through the BES Applications menu. The ability to deploy updates
and blacklist applications is a clear security advantage of BES.
Carriers can do the same through BIS, but there has not yet been a major
security outbreak necessitating such a response.