• No results found

An Example of Reconstructing IPC SMS

3.4 Automatic IPC Unmarshalling

3.4.5 An Example of Reconstructing IPC SMS

As systematically evaluating the Oracle’s reconstruction capabilities on every possible object (over 300+ AIDL objects alone) is superfluous, we introduce a representative ex- ample which exemplifies all of the Oracle’s unmarshalling capabilities. Let us consider an app that sends an SMS as our running example. The Java code that corresponds to the SMS behaviour (i.e., creating an Intent and invoking a remote method) can be seen in Figure 3.8 (a). Typically, application code for sending an SMS includes invok- ing the sendTextMessage method of SmsManager, with the destination number (e.g., “123456789”) and the SMS text (e.g., “Hello”) as parameters. It is also optional to include one or two customized PendingIntents, which may be broadcast back to the client app depending on the outcome of the service (e.g., successful send).

As explained previously, PendingIntent objects are passed by reference, rather than being directly marshalled. To keep track of such data, CopperDroid is also aware of any IBinder handles that reference the PendingIntent, by analysing previous ioctlcalls sent from the client app to the IActivityManager. Indeed, all Binder trans- actions result in at least two ioctl system calls, as shown in Figure 3.8 (b).

When our sendText is invoked, we see one ioctl used to locate the SMS service and another used to invoke the sendTextMessage method. See Figure 3.7 message 4 for the latter, which is also the main message sent to the Oracle for unmarshalling. Fur- thermore, if the second ioctl includes a pass-by-reference parameter (e.g., a handle to a PendingIntent) CopperDroid locates the third ioctl with the actual referenced object (e.g., PendingIntent saying “SENT”) and sends it to the Oracle as well. This handle/object pair generation can also be seen in Figure 3.7 (page 72) in transactions 2 and 3, and the handle can be seen used in the sendText invocation in message 4.

From a high-level perspective (e.g., Java methods), sending an SMS by roughly cor- responds to obtaining a reference to an instance of the class SmsManager, the phone SMS manager, and invoking its sendTextMessage method (last line of Figure 3.8 (a)). This invocation includes the necessary method parameters including the destination phone number and the text message as the method arguments. Alternatively, on a lower level, the same action corresponds to locating the Binder service isms and remotely invoking its sendText method with same arguments. From this low-level perspective, the same actions correspond to the sender application invoking two ioctl system calls on /dev/binder: one to locate the service and the other to invoke its method.

CopperDroid thoroughly introspects the arguments of each binder-related ioctl system call to completely reconstruct each remote, IPC, invocation. This allows Cop- perDroid to infer the high-level semantic of the operation. In particular, we focus our

PendingIntent sentIntent = PendingIntent.getBroadcast( SMS.this, 0, new Intent("SENT"), 0); SmsManager sms = SmsManager.getDefault(); sms.sendTextMessage( "123456789", null,

"Hello", sentIntent, null); (a) SMS send behaviour at app Java level

including creating a PendingIntent

sentIntetfor method parameter four.

ioctl(0x14, BINDER_WRITE_READ, 0xbedc93e8) = 0 ioctl(0x14, BINDER_WRITE_READ, 0xbeb69508) = 0 ioctl(0x14, BINDER_WRITE_READ, 0xbeb693e8) = 0 (b) SMS send PendingIntent ioctls. Third parameter points to serialized data, see Figure 3.5. BINDER_TRAN (from binder transaction data):sentIntent =

android.app.PendingIntent = Intent("SENT"))

BINDER_REPLY (from binder transaction data):sentIntent =

android.app.PendingIntent{ Binder:

type = BINDER_TYPE_HANDLE flags = 0x7F|FLAT_BINDER_FLAG_ACCEPTS_FDS

handle = 0xa cookie = 0xb8a58ae0 }

BINDER_TRAN (from binder transaction data): com.android.internal.telephony.ISms.sendText(

destAddr = "123456789" srcAddr = None text = "Hello"

sentIntent = android.app.PendingIntent{ Binder:

type = BINDER_TYPE_HANDLE,

flags = 0x7F|FLAT_BINDER_FLAG_ACCEPTS_FDS,

handle = 0xa, cookie = 0x0 }

deliveryIntent = null)

Oracle:com.android.internal.telephony.ISms.sendText(

destAddr = "123456789" srcAddr = None text = "Hello"

sentIntent = android.app.PendingIntent("SENT")

deliveryIntent = null

(c) Simplified sendText method (including PendingIntent) reconstruction produced by Copper- Droid and the Oracle, using the binder transaction data retrieved from the ioctl.

Figure 3.8: CopperDroid reconstructed sendText example.

analysis on Binder transactions, i.e. IPC operations that actually transfer data. This is also responsible for RPC. To identify these communications, CopperDroid parses the memory structures passed as parameters to the ioctl system call and identifies Binder transactions (BC TRANSACTION) and replies (BC REPLY). Refer back to Figure 3.5 (page 67) for ioctl payload layout, where BC TR is shorthand for binder transaction. In the next step, CopperDroid identities the InterfaceToken. In our example this is

ISms, albeit simplified. The entire token com.android.internal.telephon-

elif (InterfaceToken, "com.android.internal.telephony.ISms"): db_parcel_ISms(parcel, code) if (code == TRANSACTIONS["TRANSACTION_sendText"]): text.append("method: sendText") text.append("string") text.append("destAddr={0}".format(parcel.readString16())) text.append("string") text.append("scAddr={0}".format(parcel.readString16())) text.append("string") text.append("text={0}".format(parcel.readString16())) text.append("android.app.PendingIntent")

text.append("sentIntent = [PendingIntent N/A]") text.append("android.app.PendingIntent")

text.append("deliveryIntent=[PendingIntent N/A]")

Figure 3.9: AIDL example for marshalling ISms.sendText method.

the AIDL description, as also seen in Figure 3.9. Normally the marshalling description would contain more if cases for varying codes, but in our running example the code is sendText, so that is the only one we are showing.

From this figure we see the first three parameters of the invoked method are String types, and can be read as primitives. The fourth parameter to the sendText method, however, is a PendingIntent. While unmarshalling this non-primitive type, a handle is found instead of a CREATOR field. The Oracle handles this IBinder type by identi- fying and finding the referenced marshalled data and unmarshals the actual Intent as a complex class object. Normally this recreates all object fields, including empty ones, so a simplified version containing only essential data can be found in Figure 3.8 (c).