I was using geo2.pl GPS/GPRS location tracking device for some time. Wasn’t best experience – frequent system failures (on device and on geo2 server side), lack of competent support, lack of information to users (once it died for a month without ANY information from geo2 company). So if you considered buying geo2 product – forget about it. With such quality it’s not worth your money. Especially that they rose monthly price over 300%. But if you have hardware already…
- Telit GE863-GPS GSM/GPRS module programmable in Python Language
- 1575R-B G GPS antenna
- STMicroelectronics LIS302DL MEMS motion sensor 3-axis – ± 2g/± 8g smart digital output “piccolo” accelerometer (not sure if I found correct chip; hard to tell from the device itself)
- NXP PCF8574 Remote 8-bit I/O expander for I2C-bus
- Silabs CP2102 USB to UART Bridge
- TI LM2575S-5.0 1-A Simple Step-Down Adjustable Voltage Switching Regulator with Output Enable
- Maxim MAX890L 1.2A, Current-Limited, High-Side P-Channel Switch with Thermal Shutdown
There are two serial ports available on this unit. One provides GPS coordinates in NMEA format and is available through USB connector outside the device. The other serial port is available internally at JP1 connector (see picture). Any USB-serial adapter will do (I used Profilic PL2303 based one in form of old Nokia CA42 cable).
#LSCRIPT: free bytes: 1944638
“boot.py” is started after powering on geo2 device. You can change boot mode to “start after 10 seconds” and also change boot file to not existing file to prevent it from running any script. Finally reboot device. You have few seconds after powering on geo2 device to do that – otherwise boot.py will start.
Now see what geo2 software prints for us. We will start “boot.py” without a reboot:
import main # precompiled from main.pyo
import protocol # precompiled from protocol.pyo
import marshal # builtin
import gps # precompiled from gps.pyo
import gsm # precompiled from gsm.pyo
import config # precompiled from config.pyo
import device # precompiled from device.pyo
import List # precompiled from List.pyo
import acc # precompiled from acc.pyo
import IIC # builtin
import io # precompiled from io.pyo
(now it will periodically print “main” until some bad thing happens).
Can we see what geo2 software does? Yes, we can. There is “AT#RSCRIPT# command that prints content of the file. Unfortunately geo2 files were uploaded with a option disabling RSCRIPT for most of uploaded files.
Fortunately we can read the files from own python script. Someone wrote scripts for this already. telit-pyo.py script from telit-862-python-tools github repository when run on Telit device will print content of all “*.py” scripts to serial console output (in hex, with additional headers). Then decode-telit-pyo.py script will produce raw files from serial console log.
We need small modifications for our purposes – we have to patch telit-pyo.py script to also print content of “config” and “*.pyc” files (and also skip printing itself).[crayon-58d1077362624319252924/]
With this we end up having all files from geo2 device. There is another problem – most of these is “pyc” which is not raw source code. It’s python byte code, not really human readable.
decompyle – Python Decompiler comes to help. It’s not developed anymore (there is paid commercial service based on it though) and hard to compile. I’ve built it with python 1.6 and 2.7 after some patching.
With decompyle we can get more readable form of byte code files.
First look and – quality of geo2 code seems to be quite low.
GPRS part registers with “apn.o2.pl” APN (previously geo2 company was owned by o2.pl and, no, it wasn’t much better experience then) to a PlusGSM network.
Device talks with IP 188.8.131.52 on port 6288 (TCP connection). There seems to be no real authorization (yikes!) when talking to the server. Pseudo authorization is based on device IMEI and value stored in config file (as “CODE”).
GPS when no fix is found is… restarted after some time (300s), then restarted again, and again, and again (with longer periods each time).
Accelerometer is accessed over I2C and used to detect if device is moving (and then transmit new coordinates). It is initialized with such values:
_ADDRESS = 28
_INIT = ‘g’
_FILTER = ‘x07’
_SENSITIVITY = ‘x04’
# i2c device at _ADDRESS
_i2c.readwrite((‘ %s’ % (_INIT)), 0)
_i2c.readwrite((‘!%s’ % (_FILTER)), 0)
_i2c.readwrite((‘2%s’ % (_SENSITIVITY)), 0)
Configuration is stored in “config” file. This file can be read directly with “AT#RSCRIPT”.
3, # CONF_VER
‘8xff)’, # CODE (used in authorization header)
”, # PIN
1, # ROAM_OFF
0, # ROAM_ZONE_ID
, # ROAM_ZONE
0, # ROAM_STATE
-1, # JAMMER_DATE
0 # DELAY
The device has a code that allows to run (via eval()) ANY code that’s sent from remote geo2 server (idea was to allow remote debugging I think). Good that there is no microphone available on the geo2 device since Telit chip is capable of establishing audio channel and thus allowing remote audio spying.
It is also possible to upload few version of software files remotely. “updater.log” stores some information about the process:
L5;L8;L10 gsm.pyo;L14 main.pyon;L10 config.pyo;L14 protocol.pyon;L10 acc.pyo;L14 kernel.pyon;L14 device.pyon;L14 gps.pyon;L10 io.pyo;L10 List.pyo;L10 debug.pyo;L17;L21;L25;L27;L29;L30;