Setting a package as Device Administrator with StageNow, reversing the DevAdmin class name

I had to perform a simple task recently: set up the Battery Swap application on out TC51 as a Device Administrator, so that it can do its battery swapping preparations correctly (for some reason it’s not set up as such by default). MX and StageNow allow this via the DevMgr CSP. But that CSP requires Package Name and Class Name. Let’s find out and do some more package dumping for fun and profit!

Finding the package name

First, let’s find out, how the Battery Swap application is actually called. There are two ways of doing it: guesswork (works quite often!) and tracking the windows.

Let’s see which installed packages have the word “swap” in them:

>adb shell pm list packages | grep swap

Instant hit! (Yes, I cheated a little and did not include the much less impressive search for “battery” 🙂 ).

Tracking the Windows
Sets see what we can do if the app cannot be easily found in the list of installed packages.

Every time an application is launched, the Android’s window manager, called Activity Manager, will drop a line in the ADB log, which can be viewed via logcat or Android Monitor (both parts of Android SDK).

I have launched Android Monitor from the SDK, emptied the existing log and entered the filter tag:AcitivtyManager. Afterwards, I have started the Battery Swap app from the launcher. And here’s what I saw:

I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.zebra.hotswap/.MainActivity (has extras)} from uid 10026 on display 0

So, now we know the name and even the screen that gets displayed.
Let’s find out the class name!

Finding the class name

If this were a simple Intent exercise, the MainActivity screen name we have gotten from the previous step would have been enough. But here we need to find the Device Administrator class name, which most likely will not even be associated with any screen, doing some background work instead.

OK, let’s dump the package and see what we can get from there:

>adb shell pm dump com.zebra.hotswap > com.zebra.hotswap-dump.txt

How, inside the file we need to see, which resolvers are available.

Activity Resolver Table:
  Non-Data Actions:
        7a0b757 com.zebra.hotswap/.MainActivity

Receiver Resolver Table:
  Non-Data Actions:
        b94c244 com.zebra.hotswap/.DeviceAdminSample
        61f9f2d com.zebra.hotswap/.BootCompletionIntentReceiver

OK, so this application only has one screen MainActivity, which we’ve already seen before via the monitor. We can actually try launching it:

am start com.zebra.hotswap/.MainActivity

This should bring the Battery Swap screen. But this is not what we need! So let’s look further.

The app is subscribing to the DEVICE_ADMIN_ENABLED broadcast, stating that DeviceAdminSample receiver should process it. This is actually what we are looking for, according to the Android documentation!

We’re almost there, now we need to test!

Testing with StageNow

In StageNow I am creating an XPert Mode profile with a single DevAdmin setting

  • Device Administration Action: Turn On As a Device Administrator
  • Package Name: com.zebra.hotswap
  • Class Name: com.zebra.hotswap.DeviceAdminSample (note that there is no / – we need the Java class name, not the receiver component name)

Testing this setting was successful:

What if we had to go deeper?

Imagine a theoretical situation, where you need to find yet another class name, not exposed via any Activities, Receivers, etc. What can we do?

First, we need to think why we need this class name? If it is not accessible via any exposed app components – how can we use it?

Second, if we still need it, we can rip the class names from the app itself. Usually, this means getting the APK file, unZIPping it and using the dexdump.exe from Android SDK Build-Tools to get the list of everything, including the class names (google for details).

When dealing with system apps (that came with the firmware) it could be that APK has no classes.dex file! This means that the app was pre-ODEXed (pre-optimized) and we need to look for the executable code elsewhere. BTW, the Battery Swap is a prime example for it. It this case, we need to pull the ODEX file and use a tool called Backsmali to get the class names from there (instructions here).

In my case the whole sequence looked like this (minor edits for brevity):

>adb shell pm path com.zebra.hotswap

>adb shell find /system/app/HotSwap/ | grep odex

>adb pull /system/app/HotSwap/oat/arm64/HotSwap.odex
...progress here...

java -j backsmali.jar x HotSwap.odex
//x means "de-ODEX"
... throws an error saying that it can't load classes in general
... this means we need to provide the basic framework files in the same directory first

adb pull /system/framework/arm/boot.oat
...progress here...

java -j backsmali.jar x HotSwap.odex
...progress here...

In the end, a directory called “out” is created. In it there is a bunch of files, each one has a class name at the very top, which can be used for further testing.


We have reviewed how to use the essential Android ADB/shell commands and tools such as pm,am, dumpsys package and Android Monitor in order to find package and class names for a Device Administrator component. Now the app will no longer be at the mercy of the user and will function correctly from the start!

What are your thoughts? Was it useful? Let me know!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at

Up ↑

%d bloggers like this: