This blog post is a mirror and a more detailed representation of the materials I’m talking about at Kopi Darat Python Indonesia - December 2013. Slides can only say so much, here is where the intimacy starts.
Warning
Any and all of the information including source code available here are for educational purposes. Please use them responsibly. That being said, all codes are basic implementations only. Please get your hands dirty.
All codes are tested on the following configuration (specs):
- Python 2.7.2 on OS X Mavericks 10.9.1
- Google Nexus 4 - rooted - Kitkat 4.4 ROM
- MongoDB 2.4.6
Materials & Repo Access
All of the source code are available on the following Github repos.
- Ngintipbot - https://github.com/tistaharahap/ngintipbot
- ngintipd - https://github.com/tistaharahap/ngintipd
Android
Android as most of us know (or not) is an OS for a wealthy option of gadgets, embedded devices and also laptops. Long story short, Android is Linux based with Java as its frontend exposed through its SDK.
However, not everything is Java. Android has what it’s called Java Native Interface (JNI). So we can do things in Java, C/C++ and vice versa. Head on to Android NDK for more info.
The part of Android I’m talking about is not necessarily about native C/C++ developments on Android. It’s a nice to know knowldge to get a bigger picture of Android’s internals. Here’s a great Youtube video about the matter.
Rooting Android
This part is for you to figure out. But, if you happen to be using a Nexus 4, you can go here.
Rooting your phone is required in order to try out the codes.
Introducing Ngintipbot
Ngintipbot is an iconless (supposedly) Android app. Its main purpose is to monitor the items I would want to be monitored which are the items below.
- Line -
root
required - Whatsapp -
root
required - Remote Upload of Data -
root
required - Call Recording -
root
required - SMS
- Location
- Phone Logs
- Contacts
- Remote Mic Activation
How Ngintipbot Works
Here’s a quick generals on how Ngintipbot works and how it doesn’t.
- Install Ngintipbot’s APK
- Run it with one of 2 ways, the icon from the launcher or a specific SMS format
- Eitherway, it will start Ngintipbot’s Service and make it a
STICKY
service - The service will create a
PendingIntent
which will set offAlarmBroadcastReceiver
to be invoked every 1 hour - When
AlarmBroadcastReceiver
is invoked, Ngintipbot will try to passively sense the device’s current location - After getting a lock on location, Ngintipbot will read contents from Line, Whatsapp and SMS, pack it and send the whole data to a
ngintipd
instance somewhere on the Internet
All of the juicy stuffs are at Utils.java
. The methods to read contents from Line, Whatsapp and SMS are defined there.
The Main Activity
The main activity contains nothing. Consider it as a placeholder only.
There’s nothing there right? Why? A simple answer is because Activities does not have a predictable lifetime. You can’t keep Activities to always run on the background. That’s why most of the logic are delegated into Services.
Intipbot Service
This particular class interest is with stated before which is about starting the Service as a STICKY
service. In particular is with the source code below.
By returning Service.START_STICKY
we are simply making the Service to be constantly recreated if needed. A better explanation from Android’s documentation is available here.
Broadcast Receivers
The Service above is actually started from one of three possibilities which are a direct launch of the app, a specific SMS or when the device is booted. All of these are possible by registering a BroadcastReceiver
into the manifest like below.
The receiver which is StartupReceiver
simply triggers an Intent
invocation to start IntipbotService
.
Sensing Location
I guess this is relatively the easy part. Tutorials to do this are plentiful so I won’t talk much about this. My implementation after we get a lock on a location is where the more interesting action happens.
Reading & Receiving SMS
In order for us to be able to read & receive SMSes, the app must declare the permission to do so.
Reading SMS
I like JSON
and this is why my implementation is actually read SMSes and convert them into JSONArray
s which will then return its String
representation to be POST
ed later on.
Receiving SMS
The current implementation doesn’t actually parse the content of any SMS. It simply just invoke StartupReceiver
. This can be a good after hours tinkering don’t you think?
Privileged Process Running
Next step is to gain privileged rights. I implemented this at Utils.java
statically. There’s nothing special about this. One thing to keep in mind is to do proper error parsing if it so happens the app didn’t get privileged rights.
My implementation does not have that particular error management. Please do so.
Reading Line & Whatsapp
Both of these apps are actually storing their message database in an SQLite
flat file database. If you’re interested in extracting the databases without the app, the path is below.
/data/data/jp.naver.line.android/databases/naver_line*
/data/data/com.whatsapp/databases/msgstore*
Now with the app, I’m actually tar
-ring the databases, create a directory called .goog
on the SDCARD, upload to ngintipd
and delete the .goog
directory afterwards.
ngintipd
Okay ngintip is Indonesian for peeking so it’s only right to name the daemon ngintipd
. As the name implies, this daemon is always ready to receive data from Ngintipbot
. Written in Python and at the current development state, acts only as a storage. Further development should process SQLite
databases and manipulate.
Again there are nothing special yet, it’s basically a one file daemon.
EOF
This concludes the talk. Codes and implementations are still minimum but I believe it’s ready to be a foundation of something more ambitious so to speak. Cheers!