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.
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 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.
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.
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.
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 -
- Whatsapp -
- Remote Upload of Data -
- Call Recording -
- Phone Logs
- 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
- The service will create a
PendingIntentwhich will set off
AlarmBroadcastReceiverto be invoked every 1 hour
AlarmBroadcastReceiveris 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
ngintipdinstance 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.
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.
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.
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
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.
JSON and this is why my implementation is actually read SMSes and convert them into
JSONArrays which will then return its
String representation to be
POSTed later on.
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.
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.
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.
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!