Welcome back to the Awesome Android eXteme Hacking Tutorial. Hope you are ready for some more awesomeness :). In the last issue (http://papermint-designs.com/dmo-blog/2016-04-awesome-android-extreme-hacking--part-i) we learn how to create and run a C application on our Android phone. That allows you to build almost any application that does not require access to special features on your phone, in other words, pretty much any standard console based UNIX application.
Now we are going one step further hacking into your phone sensors. Yes, you phone is full of sensors and peripherals: Buttons, Touchscreen, accelerometers, gyroscopes and even temperature and pressure sensors. Android provides APIs to access those sensors from Java in a convenient way, but we want to hack into them, because that is a lot more awesome!... So, let's start.
The first thing we need to know is that the sensors are managed by the kernel and exposed to the user space through a device driver... you know, those files in the /dev folder. For the specific case of the sensors we will have to look into the so-called input devices. These devices are used by the Linux kernel to deliver events to the user space whenever something needs to be reported... This is how keyboards, mouses or joysticks reports which key had been pressed or in which direction the mouse or joystick have moved.
As you already know, or at least you can imagine, not all devices provide information this way, however, this seems to be the way Android had chosen to report data from sensors.... Let's do a quick check.
First, check that you PATH allows you to run adb and get into your device. Then, use the getevent tool to get a list of sensors and start receiving events. This is what getevents shows on my Samsung S4.
NOTE: Press CTRL+C after running the command to stop receiving events and to be able to check the list of devices.
http://papermint-designs.com/picoflamingo/download/aaxh02-code.tgz Happy hacking!
Awesome Welles
Awesome Android eXtreme Hacking. Part II. More sensors
Awesome Android eXtreme Hacking. Part III. What a Shell!
Awesome Android eXtreme Hacking. Part IV. GNU/Linux on your Pocket
Android Development for Web Programmers
Add a Remote Shell to your Android App
■
~/aaxh $ adb shell / $ getevent add device 1: /dev/input/event19 name: "sec_touchkey" add device 2: /dev/input/event2 name: "max77693-muic" add device 3: /dev/input/event0 name: "pmic8xxx_pwrkey" add device 4: /dev/input/event17 name: "apq8064-tabla-snd-card Headset Jack" add device 5: /dev/input/event16 name: "apq8064-tabla-snd-card Button Jack" add device 6: /dev/input/event18 name: "gpio-keys" add device 7: /dev/input/event15 name: "ssp_context" add device 8: /dev/input/event14 name: "step_cnt_sensor" add device 9: /dev/input/event13 name: "step_det_sensor" add device 10: /dev/input/event12 name: "sig_motion_sensor" add device 11: /dev/input/event11 name: "geomagnetic_sensor" add device 12: /dev/input/event10 name: "temp_humidity_sensor" add device 13: /dev/input/event9 name: "proximity_sensor" add device 14: /dev/input/event8 name: "light_sensor" add device 15: /dev/input/event7 name: "gesture_sensor" add device 16: /dev/input/event6 name: "pressure_sensor" add device 17: /dev/input/event5 name: "gyro_sensor" add device 18: /dev/input/event4 name: "accelerometer_sensor" add device 19: /dev/input/event1 name: "sii8240_rcp" could not get driver version for /dev/input/mice, Not a typewriter add device 20: /dev/input/event3 name: "sec_touchscreen"You would probably get a quite different list of sensors. Do not panic. In this tutorial we will be using the touchscreen (device 20 in the list above) ... and ... every Android phone has one of those :). Now we need to find out how to read and interpret those events. As you my had noted, every device has a /dev entry associated. Those are the files we have to read in order to get the data we want. Let's try to read the events from the touchscreen device. You will probably have to activate the screen to get events (press the power button to get into the lock or home screen)
/ $ cat /dev/input/event3 ???Well, Those weird characters are not very useful... don't they?. We need to parse them. Fortunately for us, those input devices sends data out using a well-known format... the EEEVEEEENTTSSSS!!!. You can get more information about the whole thing reading the Documentation folder of the Linux kernel. If you do not have the Linux Kernel source code on your hard drive (shame on you), you can check the documents on-line here https://www.kernel.org/doc/Documentation/input/input.txt and here https://www.kernel.org/doc/Documentation/input/event-codes.txt. At the very end of the first link you will find the definition of the event structure that we reproduce here for your convenience.
struct input_event { struct timeval time; unsigned short type; unsigned short code; unsigned int value; };
input_event Structure
As you can see, it is a binary structure (that is what we get all those weird martian characters on the console) containing a timestamp, a type, a code and a value. The possible values for those three last fields are described in the second kernel document linked above.
The output from getevent is pretty useful, but in order to get a better insight on our phone's sensors, it would be very useful to get a more comprehensive description of the events. And now is when evtest.c (http://elinux.org/images/9/93/Evtest.c) comes to the rescue. This is a standard GNU/Linux application that you can easily find on Internet (we had already provided the link :). A version is included in the source code package for this tutorial. The most interesting thing about this application is that it provides a very convenient skeleton to develop our sensor monitor applications.
Anyway, let's compile it, upload it and run it (check part I of the AAXH). You should get an output like this (remember to change your device if required)
/data/local/tmp $ ./evtest /dev/input/event3 Input driver version is 1.0.1 Input device ID: bus 0x18 vendor 0x0 product 0x0 version 0x0 Input device name: "sec_touchscreen" Supported events: Event type 0 (Sync) Event type 1 (Key) Event code 325 (ToolFinger) Event code 330 (Touch) Event type 3 (Absolute) Event code 47 (?) Value 0 Min 0 Max 9 Event code 48 (?) Value 0 Min 0 Max 255 Event code 49 (?) Value 0 Min 0 Max 255 Event code 50 (?) Value 0 Min 0 Max 255 Event code 53 (?) Value 0 Min 0 Max 1079 Event code 54 (?) Value 0 Min 0 Max 1919 Event code 57 (?) Value 0 Min 0 Max 65535 Event code 59 (?) Value 0 Min 0 Max 255 Event code 60 (?) Value 0 Min 0 Max 90 Event code 61 (?) Value 0 Min 0 Max 1 Event type 5 (?) Event code 22 (?) Testing ... (interrupt to exit)Pretty good. This tool already gives us some details about the events we should expect from the device. We can try to wonder what they mean or we can just swipe our finger on the screen and see what we get: Note: Remember to switch on the screen if you are not getting any events
... Event: time 140136.107859, type 1 (Key), code 330 (Touch), value 1 Event: time 140136.107889, type 3 (Absolute), code 53 (?), value 85 Event: time 140136.107889, type 3 (Absolute), code 54 (?), value 1129 .... Event: time 140136.207011, -------------- Report Sync ------------ Event: time 140136.218760, type 3 (Absolute), code 53 (?), value 186 Event: time 140136.218760, type 3 (Absolute), code 54 (?), value 1111 Event: time 140136.218760, type 3 (Absolute), code 60 (?), value -90 Event: time 140136.218790, -------------- Report Sync ------------ Event: time 140136.230479, type 3 (Absolute), code 53 (?), value 246 Event: time 140136.230479, type 3 (Absolute), code 54 (?), value 1106 Event: time 140136.230509, type 3 (Absolute), code 60 (?), value -82 Event: time 140136.230509, -------------- Report Sync ------------ Event: time 140136.418314, -------------- Report Sync ------------ Event: time 140136.429636, type 3 (Absolute), code 57 (?), value -1 Event: time 140136.429697, type 1 (Key), code 330 (Touch), value 0 Event: time 140136.429697, -------------- Report Sync ------------We had removed many of the events on the output, and just keeping the ones relevant for our current discussion. Those are the ones:
- Type 3. Code 53 -> X coordinate
- Type 3. Code 54 -> Y Coordinate
- Type 3. Code 57 -> Tap counter
- Type 1. Code 330 -> Touch
- If we touch the screen start gesture recognition.
- Initialise a counter to zero
- Get the touch screen event and extract the coordinates.
- Divide the horizontal one by width/3 and the vertical one by height/3.
- If the coordinates changed since last check, increase the counter
- Use those values to set the matrix cell to the counter
- If we stop touching the screen
- reset and start with new gesture
- Check the matrix pattern and launch the associated application
evtest.c
source code.
Let's go on. This is what we get on the adb shell console when running the application and swiping right and then left.
$ ./touch /dev/input/event3 Input device name: "sec_touchscreen" Gesture Started (0,1) = 1 (1,1) = 2 (2,1) = 3 Gesture Finished 0 0 0 1 2 3 0 0 0 Gesture Started (2,1) = 1 (1,1) = 2 (0,1) = 3 Gesture Finished 0 0 0 3 2 1 0 0 0
Our application running free!
You can see how the application detects that we had started a gesture and then starts to populate the 3x3 matrix with a counter as we swipe our finger left to right. When we detect that the gesture is finished the final matrix (or recognizer pattern) is dump for easy visualisation of the gesture. Using the counter provides us with a rudimentary way to detect the direction of the gesture.
Now we need a second function to map our gesture vector (or matrix if you prefer) to the application we want to launch. But first, let's define a convenient structure to hold our command and the associated pattern.
#define SIZE 3 #define SIZE2 3 * 3 typedef struct pat_t { char *cmd; int pat[SIZE2]; } PAT;
PATTERN structure
Based on that structure, a simple matching function will look like this:
int match_pat () { int i, j; int found; for (i = 0; pat_cmd[i].cmd; i++, found = 0) { for (j = 0; j < SIZE2; j++) { found = 0; if (_pat[j] != pat_cmd[i].pat[j]) break; found = 1; } if (found) return i; } return -1; }NOTE: This is not the final code of the function, but is convenient right now :) Now we just need to define and fill our
pat_cmd
array. Let's use a couple of gestures to start our Hello Android from Web application introduced in the previous AAXH tutorial. When we swipe from left to right on the bottom part of the screen we launch our minimal webserver, and when we swipe from bottom to top we kill it....
static PAT pat_cmd[] = { {"/data/local/tmp/hellow &", {0, 0, 0, 0, 0, 0, 1, 2, 3} }, {"kill $(pidof hellow)", {0, 3, 0, 0, 2, 0, 0, 1, 0} }, {NULL, {-1,-1,-1, -1,-1,-1, -1,-1,-1} } };
Definition of 2 simple Gestures
Not bad, but that is not that much awesome. What about launching some Android applications?. Let's modify our data structure to launch the camera with the first gesture, and a web browser pointing to an awesome site with the second...
static PAT pat_cmd[] = { {"am start -a android.media.action.IMAGE_CAPTURE", {0, 0, 0, 0, 0, 0, 1, 2, 3} }, {"am start http://papermint-designs.com/community", {0, 3, 0, 0, 2, 0, 0, 1, 0} }, {NULL, {-1,-1,-1, -1,-1,-1, -1,-1,-1} } };
Adding more convenient actions to our gestures
We are pretty sure all the readers can figure out what the two gestures defined in the structure above does. But... wait!, what is that "am start" thingy?. Good catch little grasshopper. You had spotted the Activity Manager... OMG!
The am command allows you to do a lot of stuff with the Android activities. Just type am on the command line to get a list of options, or check this site for more human-readable details (http://developer.android.com/tools/help/adb.html#am). For the lazy reader, what we are doing, is using the Activity Manager to launch standard Android application using Intents.
An intent is something like a generic application execution. We tell the system, for instance, that we want to see a web site, and then the system, either uses the default application for web browsing or provides you with a list of applications that can be used for that INTENTION. Our example uses the camera and the web browsing, but you can experiment with others. Check this page for a extensive list (https://developer.android.com/guide/components/intents-common.html).
So, this concludes the second part of the Android Awesome eXtreme Hacking tutorial. We still have to say a couple more things about sensors, but that will come later.
You can download the code from this link:http://papermint-designs.com/picoflamingo/download/aaxh02-code.tgz Happy hacking!
Awesome Welles
RELATED POSTS
Awesome Android eXtreme Hacking. Part I
Awesome Android eXtreme Hacking. Part II. More sensors
Awesome Android eXtreme Hacking. Part III. What a Shell!
Awesome Android eXtreme Hacking. Part IV. GNU/Linux on your Pocket
Android Development for Web Programmers
Add a Remote Shell to your Android App
■
CLICKS: 3927