Open the ServiceMode menu programmatically in Android

How to programmatically open the Android ServiceMode menu on Samsung phones?
Manually, I can do this by typing the code ussd * # 0011 #.

enter image description here

+7
android samsung-mobile mobile galaxy
source share
4 answers

It was a challenge, and for several hours I was looking for a solution. But I'm afraid that I do not have good news.

1. First attemp, Intent.ACTION_DIAL

It is true that at first it was possible to directly call USSD codes from the application (using the intent Intent.ACTION_DIAL) and even from the website using the tel: scheme. This opens the dialer, and puts the right number. Since when you put the last #, the code receives an automatic transfer, it was almost transparent to a user whose interaction was not required. But in fact, this was considered a system vulnerability, because someone could write malicious software or even more, embed malicious code on a website that could even erase your phone or block a SIM card. You can read about it, for example, in this link. As of September 2012, it seems that Samsung has finally fixed this vulnerability , so, for example, your S3 is not capable of it. At this point, it will be difficult to find any device that is still vulnerable.

2. Second attempt, workaround

Well, everything in Android is an application, even the phone itself is an application. So why were we unable to reproduce his code? And actually, what happens when a user manually sends ussd? There were also possible answers:

  • The phone sends the code to the provider and waits for a response, or
  • The phone is doing something locally

Itโ€™s easy to check: I put my phone in flight mode, so if he needs to send the code, we hope he canโ€™t. It was exactly as I expected: I typed the code and the ServiceMode screen appeared! And it was empty, so we can say that the dialer opens the system application, and this application calls the provider. Its easy to find out what this app is. On Samsung devices, at least on S4, this is the name ServiceMode. You can find it in Settings > Application manager > All . Therefore, we can try to figure out how it starts more with one of them:

2.1. Reading phone application code

I tried, but it was rather confusing at the beginning, so I moved to option 2

2.2. Verify Maintenance Mode Application

I opened ES File Explorer> Application Manager. I connected the phone, and in the phone / backups / applications I had servicestatus apk. a few minutes later or after reverse engineering, I had a manifest file, as shown how it is used. There I could see many events, as well as several broadcast receivers. I did not know what I was more afraid of.

2.2.1 Try the steps.

Since we know that we can open a specific application from another, I will try to write a simple application that opens one of these actions. It is as simple as:

 Intent i= new Intent(Intent.Action_MAIN); i.setClass( "package name", "class name"); startActivity(i); 

Since this application is not intended to be opened from the launch icon, it has no activity with an intent filter that allows us to know that this is the main action. Therefore, I should try at least a few of them. But in any case, I saw something that I did not like. I will tell you later.

I tried, but, as expected, I can not open this activity. I get an exception not found in the job. So try with the receiver. At least it will be fun.

2.2.2 Try using receivers.

There are a few, but I especially liked this intent filter:

  <intent-filter> <action android:name="android.provider.Telephony.SECRET_CODE" /> ... 

Looks nice. I went to Telephony.java, and there I could see this:

  /** * Broadcast Action: A "secret code" has been entered in the dialer. Secret codes are * of the form *#*#<code>#*#*. The intent will have the data URI:</p> * * <p><code>android_secret_code://&lt;code&gt;</code></p> */ public static final String SECRET_CODE_ACTION = "android.provider.Telephony.SECRET_CODE"; 

It looks great, its specific intention, maybe we need a scheme not "tel:", but "android_secret_code: //", and probably the codes should be in a different internal format. I tried, more or less just for fun, because I knew that there is the same problem that I saw in the actions, and this is what:

  <permission android:name="com.sec.android.app.servicemodeapp.permission.KEYSTRING" android:protectionLevel="signatureOrSystem" /> 

An application declares this permission, and each component uses it. So, either you know how to declare and establish a signature, or you are a system application. Otherwise, you cannot interact with this application at all.

Of course, you could not even think of creating your own servicemode application, since you could not carry out such communication with the provider without being a system application (since you need to go through some firmware applications that will say sad โ€œwho do you think you are ")

conclusions

We can do nothing from his point of view, at least with a Samsung phone, and we can think that every other phone will be the same.

Alternatives

Well, really nothing good. But let's see:

Alternative 1. Find a different kind of ussd code

We know that there are 2 types of USSD. Those that, when you dial the last #, the action automatically starts, and another, for which you need to press the call button.

If you try a third-party dialer, you will see that

  • if you type code of the first type, nothing starts at all (only they can be called only for firmware)
  • You can use a different type (enter code + press call). I believe this means that such codes are less risky, since they do not change anything in the device, so they are allowed.
  • Of course, if you type the code of the first type and press the call, you will receive an error message because this code does not work.

So, if a third party can send this type of code, every application can. So, if you can try to find an alternative ussd code , of the type that starts after usser presses the call button, you can achieve what you need. In this case, you must use the intent Intent.ACTION_CALL

// if you use the ACTION_DIAL intent, it opens the dialer and puts the given number into it. // Meanwhile, if we use ACTION_CALL, the application will call directly.

 Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:"+ "*" + Uri.encode("#") + "0011" + Uri.encode("#"))); //here you woud put your alternative code startActivity(intent); 

You also need to declare this permission in your manifest.

 <uses-permission android:name="android.permission.CALL_PHONE"></uses-permission> 

You could probably find an alternative code for this, since I saw several on the Internet, but at that moment no one worked for me. You can try try

Alternative 2. Wait for the official api to appear

On the project android project page in coogle code , a request appears to add support for the USSD API. He has a lot of subscribers, but he is quite old (more than 5 years), I am afraid that this is not very good. In any case, this can happen, probably, the android will consider preparing api so that the application can declare some permissions and make requests for some codes. But, I know, this can always wait.

So what to say. Good luck finding a solution or an alternative to your application. I wish my studies were more fruitful :(

+14
source share

I think I have a solution.

By running the following code on the root phone, you should open Samsung ServiceModeApp (service mode shown in this message). Programmatically, I think that you can run anything if registered as root. However, there are problems such as:

  • Root phone . If you are creating publishing apps, consider that less than 2% of all Android devices are implemented,
  • Very specific application . This code below works on a specific version of the Samsung device (I launched it on the Galaxy SIII GT-9300). It cannot work in other models and, of course, will not be in other brands. You must re-execute each case.

Acquire that 0011 is an argument that you must pass into action. Code follows:

 PackageManager packageManager = this.getPackageManager(); if (packageManager != null) { measure_intent = new Intent(Intent.ACTION_MAIN). addCategory(Intent.CATEGORY_LAUNCHER).setComponent(new ComponentName( "com.sec.android.app.servicemodeapp", "com.sec.android.app.servicemodeapp.ServiceModeApp")); measure_intent.putExtra("keyString", "0011"); ResolveInfo resolved = packageManager.resolveActivity( measure_intent, PackageManager.MATCH_DEFAULT_ONLY); if (resolved != null) { startActivity(measure_intent); return; } else { Toast.makeText(this, "version not implemented", Toast.LENGTH_LONG).show(); } } 

I got to it by pulling out ServiceModeApp from the Android / system / app directory, then decompiling the .apk file, and then analyzing its code. Hope it helps! :)

+3
source share

FWIW: ServiceMode (SM) access depends on both HW and SW, and each manufacturer tries to repeatedly hide the SM functionality at each iteration of the AOS API. SM is actually located in the FW modem, and what you see is just creating a Java wrapper and presenting the results of various calls in the RTOS modem. (You can check your FW modem to verify this.) In addition, with recent Samsung / HTC FW stocks, they also require the inclusion of certain files in the / efs / directory.

0
source share

Not quite a fix, but with Intent.ACTION_DIAL you can display the code in the dialer (# * # 4636 # * #), then long press and cut, then long press and paste do their job (in any case, on the Moto G5s +) ) Itโ€™s still easier for me to do this from my application than to call a separate dialer, but, as I said, this is not quite a fix.

0
source share

All Articles