47

I am trying to create an application that will have a service running in the background that will be capable of injecting touch screen events into whatever activity is running. I am able to inject events into an Activity that is part of my application by calling Instrumentation.sendPointerSync(motionEvent); However if I try to do this without an activity from my application running I get a permission error saying that I don't have the INJECT_EVENTS permission. I've added this permission to my manifest like this: <uses-permission android:name="android.permission.INJECT_EVENTS"></uses-permission> Its still throwing the same permission exception though. After a bit of searching I've gotten the answer that in order to receive the INJECT_EVENTS permission your app must be signed by the same signature that the system is signed with. I am unclear however what exactly this means. I am going to have to find a custom rom build it and sign it with the same signature that the application is signed with. Then install the custom rom on my device, then install my app and I'll be able to inject the touch events correctly? If this is the case am I better off starting with a custom rom that is already put together, like one from this page Or is it a situation where I am going to need to grab a git copy of the android project and build the whole thing myslef? And either way does anyone know of a place you could point me that would get me working in the right direction to make this happen?

FoamyGuy
  • 46,603
  • 18
  • 125
  • 156
  • 6
    You are correct in saying that you will need to bake this app into the ROM. Inject Events is a system permission that regular apps cannot be granted. – Austyn Mahoney Mar 21 '11 at 20:51
  • 2
    As I was explaining to others... this permission is not the regular type so adding it to the manifest has little effect. For this permission to work , the apk must be signed with system certificate. Not for the regular developers, only for platform makers – radhoo Jan 30 '13 at 15:43

8 Answers8

19

To inject events into a separate process, it is required to both install your app into /system/app and sign your APK with the system certificate.

1. Add permission to the app manifest

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

2. Sign your APK with the system certificate

This requires that you have the AOSP source in order to build a keystore with the google keys used to build the system running on the phone.

Given you have an AOSP directory, @Eli does an excellent job of showing how to build the keystore using a nice script called 'keytool-importkeypair'

Using IntelliJ as an example, choose Generate Signed APK.. from the Build menu. Locate the keystore created above, type in the password given (e.g., android), give the key the same password, if desired. Note that the signed apk is written to the project root (!) not to the typical location (./out/production//).

3. Install into /system/app/

adb root
adb remount
adb push MyApp.apk /system/app

The 'installation' happens automatically. Note, however, that unlike the normal app installation process, any native libraries in your APK are not copied into /system/lib/. You will need to do that manually, if you are using the NDK to build and call your own native libraries.

Brent Faust
  • 9,103
  • 6
  • 53
  • 57
  • 1
    If you have signed with platform key, you don't have to install into /system partition in addition. – Rahul Murmuria Mar 14 '16 at 03:54
  • 3
    If you're building your app as part of a full AOSP build, you just need to add `LOCAL_CERTIFICATE := platform` to the app's Android.mk. – fadden Oct 29 '16 at 00:10
13

Actually, this is pretty simple on a rooted device. I think any app that is running off /system will get access to whatever permissions it requires. So simply manually install your App to /system (as described here http://androidforums.com/droid-all-things-root/64603-installing-apk-system-app-directory.html ):

Execute the following commands in the terminal emulator to remount the /system directory as read/write and to install the application into the /system/app directory from the SDCARD:

su
mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system
cp /sdcard/APP.apk /system/app

If you prefer to use adb from your computer, execute these commands:

adb remount
adb shell cp /sdcard/APP.apk /system/app

Several users have utilized root explorer from the Google marketplace to simplify this process.


Alternatively, check this out: How to compile Android Application with system permissions

Community
  • 1
  • 1
Yossi
  • 1,226
  • 1
  • 16
  • 31
  • Thanks for the link! How can I manually install to /system? with adb somehow? – FoamyGuy Sep 07 '11 at 02:17
  • 1
    I guess the description is a bit confusing. The line where the apk is copied from SDcard to /system/app is considered 'installing' – Yossi Oct 12 '11 at 02:27
  • 4
    I can't get this working in ICS on rooted Transformer Prime. Looking at the protectionLevel for INJECT_EVENTS permission, it says "signature", and not "signatureOrSystem" which suggests moving an app to the system partition will have no effect. Compiling with the system certifcate should work though... – barkside Sep 05 '12 at 14:13
  • 13
    Actually wrong that permission is signature based and putting the apk to system/app won't solve any problems it has to be signed with the signature which signed the rom image. – Kerem Kusmezer Jan 31 '13 at 18:54
  • 3
    For reference you can see that the INJECT_EVENTS permission is protection level "signature" and not "signatureOrSystem" here: https://github.com/android/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml#L1720 – Russell Silva Sep 24 '13 at 17:24
  • 1
    I signed my app using platform.pk8 + platform.x509.pem, also push the apk to system/app and installed it. The security exception still occurs. I am using Samsung Galaxy Note3. Is Samsung using their own platform key instead of the 1 found in "{Android Source}/build/target/product/security"??? In addition, if I included android:sharedUserId="android.uid.system" in my manifest, the app won't install. The error: "Package has no signatures that match those in shared user android.uid.system; ignoring!" – tcboy88 May 08 '14 at 10:05
  • 4
    I don't know why this is the accepted answer and has the most votes when its incorrect. Simply installing to /system/app will not grant this permission. As others say, it must also be signed with the system certificate. – Gruntcakes Nov 28 '15 at 23:57
  • When rooted: `su -c input tap 200 300` works for me across apps without having to sign anything. It's good enough for my use case. – Jappie Kerk Feb 06 '21 at 16:10
9

Using Touch Events:

  1. Sign the application with the same signature that the ROM is signed with

  2. Download keytool-importkeypair to do this

  3. Find platform.pk8 + platform.x509.pem: {Android Source}/build/target/product/security

  4. Then generate a certificate:

    ./keytool-importkeypair -k google_certificate.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias platform

  5. Now export your app from Eclipse and sign with the new certificate you generated

  6. Build ROM, flash to device, install app

Check out http://code.google.com/p/android-event-injector/

Community
  • 1
  • 1
wwjdm
  • 2,568
  • 7
  • 32
  • 61
6

Starting from API 18 there is UiAutomation class, which isn't bound to user permissions.

For more information see http://developer.android.com/reference/android/app/Instrumentation.html#getUiAutomation()

  • is it possible to simulate different touche events like single touch, and swipe using this method? Thanks. – Dania Oct 31 '15 at 15:35
  • 1
    @Dania Sure. But my answer can be a bit confusing. I assumed the author had testing purposes, which means the "service", he mentioned, will be run via adb (usually with usb connected to developer's machine). If it is a case, you have, then start from here: http://developer.android.com/intl/ru/training/testing/ui-testing/uiautomator-testing.html In that sample UI Automator testing framework is using UiAutomation class inside. You can either use UI Automator methods or get UiAutomation instance by getInstrumentation().getUiAutomation() to have more power over events. – Sergey Krasilnikov Nov 02 '15 at 06:39
  • @ Sergey Krasilnikov, Thank you for your answer. – Dania Nov 03 '15 at 14:25
  • this solution only works till android 11 – kishan verma Mar 24 '23 at 13:23
3

In case if anyone is looking for a solution to bypass this signature level permission and want to create touch events.

I looked at the source down to the C++ level where it is actually checked whether to allow the app to create touch events or not. The following is the function which actually checks if the app should be allowed or not :

bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
return injectorUid == 0
        || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
}

So the function returns true of the user id of the app is set to 0.

Now I changed the uid if my app to 0 by editing the filee /data/system/packages.xml. This file contains the uid assigned to every app. Edit this file by setting the userId attribute corresponding to your app to 0.

Now all you need is to force close the app and restart again. You will be able to bypass the INJECT_EVENTS permission.

omerjerk
  • 4,090
  • 5
  • 40
  • 57
  • Where /data/system/packages.xml will be? – Dhasneem Aug 12 '14 at 11:47
  • inside the /data partition. The device must be rooted to access that. – omerjerk Aug 13 '14 at 14:14
  • 2
    I found packages.xml. I'm developing the application as service running in background, which is started from boot completion. If I change packages.xml file, I have to rebooted it to take that uID=0, and the modified packages.xml also reverted back, while I'm rebooting. Is there any other way to chage packages.xml from /out directory? Or, Is there any other way to change the uId for my application? – Dhasneem Aug 14 '14 at 06:22
  • 2
    Changing the userId in the packages.xml does not change the user id of the application. This method isn't real. – Rahul Murmuria Mar 14 '16 at 04:15
1

I'm also having this same problem before, In the below way I over the KEY_INJECT_EVENT_PERMISSION issue.

Step 1: You need to get the Signature (for me the file name is signapk) of your Device ROM.

Step 2: Then you need to get the platform.pk8 and platform.x509.pem files.

Step 3: Generate the the debug apk of your application.

Step 4: Place all the above files in a single folder.

Step 5: Once you get all the above files run the command mentioned in below.

java -jar signapk.jar platform.x509.pem platform.pk8 your_debug_app.apk customname.apk

Step 6: After this you can get a signed apk (customname.apk) in the same folder.Once you get that run the below command.

adb install -r app-release-signed.apk

Step 7: Now the Inject_Event_Permisson will be enabled.

Refer the below link:

https://steveandro.blogspot.com/2019/09/key-injection-android.html

Stephan John
  • 331
  • 1
  • 2
  • 11
0

If you are using a physical samsung device, changing navigation type from Swipe gestures to Buttons in the device settings seems to solve this issue.

Rafsanjani
  • 4,352
  • 1
  • 14
  • 21
-1

Alright, I got this finally. Believe me when I say this, this is probably the worst solution if you can even call it that. This requires root and will disable signature verification of all packages, system wide. This can expose you to a bunch of attacks where a dangerous app replaces a normal one.

Anyways, with that out of the way here we go:

  1. Install Xposed
  2. Install XInstaller module for Xposed
  3. In XInstaller options, go to the menu named "Installations" and check the box that says "Checking signatures" and "Verifying apps"

You should be good to go after a reboot. Your app won't even need to be installed as system, it can now be run in userspace which I suppose makes developing easier since you don't need to copy to /system/app anymore

Allison
  • 2,213
  • 4
  • 32
  • 56
  • Should this work from the android emulator when running a unit test? – Jared Beach Oct 30 '15 at 01:19
  • I'm not sure. If you can get Xposed to install properly on the emulator, then it should be smooth sailing from there, but Xposed isn't well known for working on different architectures. Also: http://stackoverflow.com/questions/18142924/how-to-use-xposed-framework-on-android-emulator – Allison Oct 31 '15 at 03:52