First commit
This commit is contained in:
commit
6084eb30d6
|
@ -0,0 +1,247 @@
|
|||
Modmobmap
|
||||
==========
|
||||
|
||||
Modmobmap is a tool aimed to retrieve information of cellular networks.
|
||||
As shown in the first [presentation made at BeeRump 2018](https://www.rump.beer/2018/slides/modmobmap.pdf). This tool is able to retrieve information of 2G, 3G, 4G and more cellular network types with minimum requierement: only a phone with ServiceMode.
|
||||
|
||||
For the moment, the tool has only been tested and developped for the following devices:
|
||||
- Samsung Galaxy S3 via [xgoldmon (Modmobmap's edition)](https://github.com/FlUxIuS/xgoldmon);
|
||||
- Samsung Galaxy S4;
|
||||
- Samsung Galaxy S5;
|
||||
- Samsung Galaxy Note 2 with LTE;
|
||||
|
||||
But as it's compatible for XGold via Modmobmap's forked of *xgoldmon*, this will probably include the following devices too:
|
||||
- Samsung Galaxy S4 GT-I9500 (this is the version without LTE!)
|
||||
- Samsung Galaxy Nexus GT-I9250 (has to be rooted!)
|
||||
- Samsung Galaxy S2 GT-I9100
|
||||
- Samsung Galaxy Note 2 GT-N7100
|
||||
|
||||
Note that all devices should be rooted. In any other case, you will have to use the DFR technique by hand!
|
||||
|
||||
Also: Patches, or engines, for other devices are very much welcomed! ;)
|
||||
|
||||
Requirements
|
||||
-------------
|
||||
|
||||
Here are the following requirements:
|
||||
- Python 2 or 3;
|
||||
- Last Android SDK to run ADB: https://developer.android.com/studio/#downloads;
|
||||
- A compatible mobile phone;
|
||||
- A valid/unvalid SIM card (just in case to provide an IMSI number).
|
||||
|
||||
How to use
|
||||
----------
|
||||
|
||||
The tool is provided with a quick help that shows you the required argument as follows:
|
||||
|
||||
```
|
||||
python modmobmap.py -h
|
||||
usage: modmobmap.py [-h] [-m MODULE] [-n NETWORKS] [-o] [-s ANDROIDSDK]
|
||||
[-a ATMODE] [-f FILE]
|
||||
|
||||
Mobile network mapping tool with cheap equipments
|
||||
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
-m MODULE, --module MODULE
|
||||
Module to use (e.g: "servicemode" by default)
|
||||
-n NETWORKS, --networks NETWORKS
|
||||
Networks in MCCMNC format splitted with commas
|
||||
-o, --cached_operator
|
||||
Use operator in cache to speed up the passive scan
|
||||
-s ANDROIDSDK, --sdk ANDROIDSDK
|
||||
Android SDK path
|
||||
-a ATMODE, --at ATMODE
|
||||
AT access mode. If host put something like
|
||||
"/dev/ttyUSBxx. By default it uses ADB."
|
||||
-f FILE, --file FILE File to parse. For the moment it could be used in
|
||||
combination with AT mode host.
|
||||
```
|
||||
|
||||
Assuming the Android SDK is installed in */opt/Android*, the tool can be quickly started as follows:
|
||||
|
||||
```
|
||||
$ sudo python modmobmap.py
|
||||
=> Requesting a list of MCC/MNC. Please wait, it may take a while...
|
||||
Found 2 operator(s)
|
||||
{u'20810': u'F SFR', u'20820': u'F-Bouygues Telecom'}
|
||||
[+] Unregistered from current PLMN
|
||||
[+] New cell detected [CellID/PCI-DL_freq (4XXX-81)]
|
||||
Network type=2G
|
||||
PLMN=208-10
|
||||
ARFCN=81
|
||||
[+] New cell detected [CellID/PCI-DL_freq (6XXXXXX-2950)]
|
||||
Network type=3G
|
||||
PLMN=208-20
|
||||
Band=8
|
||||
Downlink UARFCN=2950
|
||||
Uplink UARFCN=2725
|
||||
[+] New cell detected [CellID/PCI-DL_freq (3XX-6300)]
|
||||
Network type=4G
|
||||
PLMN=208-10
|
||||
Band=20
|
||||
Downlink EARFCN=6300
|
||||
[+] New cell detected [CellID/PCI-DL_freq (3XX-2825)]
|
||||
Network type=4G
|
||||
PLMN=208-10
|
||||
Band=7
|
||||
Downlink EARFCN=2825
|
||||
[+] New cell detected [CellID/PCI-DL_freq (3XX-1675)]
|
||||
Network type=4G
|
||||
PLMN=208-10
|
||||
Band=3
|
||||
Downlink EARFCN=1675
|
||||
[...]
|
||||
```
|
||||
|
||||
Note: If the Android SDK is installed anywhere else, you can use the *-s* parameter to specify its directory.
|
||||
|
||||
Speed-up the passive scan
|
||||
---------------------------
|
||||
|
||||
When looking for operators, an AT command is sent to the modem. If you want to speed-up the scanning, you can hardcoded the operators to the following file `cache/operators.json`:
|
||||
|
||||
```
|
||||
{
|
||||
"20801": "Orange",
|
||||
"20810": "F SFR",
|
||||
"20815": "Free",
|
||||
"20820": "F-Bouygues Telecom"
|
||||
}
|
||||
```
|
||||
|
||||
Only the MCC/MNC codes are inmportant. Then you can re-launch the tool as follows:
|
||||
|
||||
```
|
||||
$ sudo python modmobmap.py -o
|
||||
=> Requesting a list of MCC/MNC. Please wait, it may take a while...
|
||||
Found 4 operators in cache, you choose to reuse them.
|
||||
Found 4 operator(s)
|
||||
{u'20810': u'F SFR', u'20820': u'F-Bouygues Telecom', u'20815': u'Free', u'20801': u'Orange'}
|
||||
[+] Unregistered from current PLMN
|
||||
[+] New cell detected [CellID/PCI-DL_freq (XXXX-10614)]
|
||||
Network type=3G
|
||||
PLMN=208-10
|
||||
Band=1
|
||||
Downlink UARFCN=10614
|
||||
Uplink UARFCN=9664
|
||||
[...]
|
||||
[+] New cell detected [CellID/PCI-DL_freq (XXX-3501)]
|
||||
Network type=4G
|
||||
PLMN=208-20
|
||||
Band=8
|
||||
Downlink EARFCN=3501
|
||||
[...]
|
||||
[+] Unregistered from current PLMN
|
||||
=> Changing MCC/MNC for: 20815
|
||||
[+] New cell detected [CellID/PCI-DL_freq (XXX-2825)]
|
||||
Network type=4G
|
||||
PLMN=208-15
|
||||
Band=7
|
||||
Downlink EARFCN=2825
|
||||
[...]
|
||||
=> Changing MCC/MNC for: 20801
|
||||
[+] New cell detected [CellID/PCI-DL_freq (XXXXX-3011)]
|
||||
Network type=3G
|
||||
PLMN=208-1
|
||||
Band=8
|
||||
Downlink UARFCN=3011
|
||||
Uplink UARFCN=2786
|
||||
[...]
|
||||
```
|
||||
|
||||
Note we have been able to detect other cells the AT command *AT+COPS* did not returned.
|
||||
|
||||
A complet list of MCC and MNC codes could be retrieved anywhere on internet and in Wikipedia: https://en.wikipedia.org/wiki/Mobile_country_code
|
||||
|
||||
Focusing some operators
|
||||
------------------------
|
||||
|
||||
It is possible to tell *Modmobmap* to only focuse on specific operators with the *-m* argument:
|
||||
|
||||
```
|
||||
$ sudo python modmobmap.py -n 20801
|
||||
=> Manual MCC/MNC processing...
|
||||
Found 1 operator(s)
|
||||
{'20801': '20801'}
|
||||
[...]
|
||||
=> Changing MCC/MNC for: 20801
|
||||
[+] New cell detected [CellID/PCI-DL_freq (XXX-1675)]
|
||||
Network type=4G
|
||||
PLMN=208-01
|
||||
Band=3
|
||||
Downlink EARFCN=1675
|
||||
[+] New cell detected [CellID/PCI-DL_freq (XXXXX-3011)]
|
||||
Network type=3G
|
||||
PLMN=208-1
|
||||
Band=8
|
||||
Downlink UARFCN=3011
|
||||
Uplink UARFCN=2786
|
||||
=> Changing network type for 3G only
|
||||
[+] New cell detected [CellID/PCI-DL_freq (XXXXX-2950)]
|
||||
Network type=3G
|
||||
PLMN=208-1
|
||||
Band=8
|
||||
Downlink UARFCN=2950
|
||||
Uplink UARFCN=2725
|
||||
```
|
||||
|
||||
Using Modmobmap with xgoldmon
|
||||
------------------------------
|
||||
|
||||
To use *Modmobmap* with XGold modems, the use of xgoldmon will be required. But for now, only the fork for *Modmobmap* works to retrieve exact information of cells via the DIAG interface, and could be downloaded in with the following URL: https://github.com/FlUxIuS/xgoldmon
|
||||
|
||||
Then after compiling, the tool *xgoldmon* could be started using the *-m* parameter like this:
|
||||
|
||||
```
|
||||
sudo ./xgoldmon -t s3 -m /dev/ttyACM1
|
||||
```
|
||||
|
||||
This will create a FIFO file that will be requested by Modmobmap later:
|
||||
|
||||
```
|
||||
$ ls
|
||||
celllog.fifo Makefile screenshot-mtsms-while-in-a-call.png xgoldmon
|
||||
```
|
||||
|
||||
Then we can start running *Modmobmap* as follows precising the AT serial interface (*/dev/ttyACM0*) and the fifo file created by *xgoldmon* (*<xgoldmonpath/celllog.fifo*):
|
||||
|
||||
```
|
||||
$ sudo python3 modmobmap.py -f /<xgoldmon path>/celllog.fifo -m xgoldmod -a /dev/ttyACM0 -o
|
||||
=> Requesting a list of MCC/MNC. Please wait, it may take a while...
|
||||
Found 4 operators in cache, you choose to reuse them.
|
||||
Found 4 operator(s)
|
||||
{'20801': 'Orange', '20810': 'F SFR', '20815': 'Free', '20820': 'F-Bouygues Telecom'}
|
||||
[+] New cell detected [CellID/PCI-DL_freq (0x7XXXX-65535)]
|
||||
Network type=3G
|
||||
PLMN=208-1
|
||||
Downlink UARFCN=65535
|
||||
Uplink UARFCN=2850
|
||||
[+] Unregistered from current PLMN
|
||||
[+] New cell detected [CellID/PCI-DL_freq (0x7XXXX-3011)]
|
||||
Network type=3G
|
||||
PLMN=208-1
|
||||
Downlink UARFCN=3011
|
||||
Uplink UARFCN=2786
|
||||
[...]
|
||||
[+] Unregistered from current PLMN
|
||||
=> Changing MCC/MNC for: 20810
|
||||
[+] New cell detected [CellID/PCI-DL_freq (0x3XXXXX-3075)]
|
||||
Network type=3G
|
||||
PLMN=208-10
|
||||
Downlink UARFCN=3075
|
||||
Uplink UARFCN=2850
|
||||
[...]
|
||||
```
|
||||
|
||||
Note: Some trouble could be expected when retrieving results from AT+COPS command. The best way is to use targeted or operators in cache.
|
||||
|
||||
Saving results
|
||||
---------------
|
||||
|
||||
The process could be stopped any time and results are save when killing the process with a keyboard interrupt signal:
|
||||
|
||||
```
|
||||
[...]
|
||||
^C[+] Cells save as cells_1528738901.json
|
||||
```
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"20801": "Orange F",
|
||||
"20810": "F SFR",
|
||||
"20815": "Free",
|
||||
"20820": "F-Bouygues Telecom"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,28 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
class _Singleton(type):
|
||||
""" A metaclass that creates a Singleton base class when called. """
|
||||
_instances = {}
|
||||
def __call__(cls, *args, **kwargs):
|
||||
if cls not in cls._instances:
|
||||
cls._instances[cls] = super(_Singleton, cls).__call__(*args, **kwargs)
|
||||
return cls._instances[cls]
|
||||
|
||||
class Singleton(_Singleton('SingletonMeta', (object,), {})): pass
|
||||
|
||||
class mKB(Singleton):
|
||||
config = {
|
||||
'verbose' : True,
|
||||
'output' : None,
|
||||
}
|
||||
data = {}
|
||||
|
||||
def output2xml(string):
|
||||
init = None
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
from core.mKB import *
|
||||
from utils.colors import bcolors
|
||||
|
||||
def Cellslogger(func):
|
||||
def wrapped(*args, **kwargs):
|
||||
result = func(*args, **kwargs)
|
||||
kb = mKB()
|
||||
if 'SM_cells' not in kb.data:
|
||||
kb.data['SM_cells'] = {}
|
||||
id_ = v = None
|
||||
try:
|
||||
id_,v = list(result.items())[0]
|
||||
except:
|
||||
pass
|
||||
#print ("Error Celllog: %s" % result)
|
||||
if id_ not in kb.data['SM_cells'] and id_ is not None:
|
||||
kb.data['SM_cells'][id_] = v
|
||||
if kb.config['verbose'] == True:
|
||||
string2print = "[+] New cell detected [CellID/PCI-DL_freq (%s)]" % id_
|
||||
string2print += "\n\r Network type=%s" % v['type']
|
||||
string2print += "\n\r PLMN=%s" % v['PLMN']
|
||||
if 'band' in v:
|
||||
string2print += "\n\r Band=%i" % v['band']
|
||||
if '4G' in v['type']:
|
||||
string2print += "\n\r Downlink EARFCN=%i" % v['eARFCN']
|
||||
elif '3G' in v['type']:
|
||||
string2print += "\n\r Downlink UARFCN=%i" % v['RX']
|
||||
string2print += "\n\r Uplink UARFCN=%i" % v['TX']
|
||||
elif '2G' in v['type']:
|
||||
string2print += "\n\r ARFCN=%i" % v['arfcn']
|
||||
print (bcolors.OKGREEN+string2print+bcolors.ENDC)
|
||||
return result
|
||||
return wrapped
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,217 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
import subprocess
|
||||
import threading
|
||||
import os.path
|
||||
import sys
|
||||
import re
|
||||
if sys.version_info >= (3,0):
|
||||
from queue import Queue
|
||||
else:
|
||||
from Queue import Queue
|
||||
|
||||
default_android_sdk_path = "/opt/android/android-sdk-linux"
|
||||
|
||||
class ADBError(Exception):
|
||||
def __init__(self, value):
|
||||
if value == 'platform':
|
||||
self.value = "The plateform is not supported for the moment."
|
||||
elif value == 'dev':
|
||||
self.value = "libRIL use an unsupported argument."
|
||||
else:
|
||||
self.value = "Unknown error: " + value
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
class AsynchronousFileReader(threading.Thread):
|
||||
'''
|
||||
ref: http://stefaanlippens.net/python-asynchronous-subprocess-pipe-reading/
|
||||
Helper class to implement asynchronous reading of a file
|
||||
in a separate thread. Pushes read lines on a queue to
|
||||
be consumed in another thread.
|
||||
'''
|
||||
|
||||
def __init__(self, fd, queue):
|
||||
assert isinstance(queue, Queue)
|
||||
assert callable(fd.readline)
|
||||
threading.Thread.__init__(self)
|
||||
self._fd = fd
|
||||
self._queue = queue
|
||||
self._stop = threading.Event()
|
||||
|
||||
def run(self):
|
||||
'''The body of the tread: read lines and put them on the queue.'''
|
||||
for line in iter(self._fd.readline, ''):
|
||||
self._queue.put(line)
|
||||
|
||||
def stop(self):
|
||||
self._stop.set()
|
||||
|
||||
def stopped(self):
|
||||
return self._stop.isSet()
|
||||
|
||||
def eof(self):
|
||||
'''Check whether there is no more content to expect.'''
|
||||
return not self.is_alive() and self._queue.empty()
|
||||
|
||||
class ADBshell(object):
|
||||
androidsdkpath = None
|
||||
def __init__(self, androidsdkpath=None):
|
||||
self.androidsdkpath = androidsdkpath
|
||||
|
||||
def _buildcommand(self, command):
|
||||
adbpath = None
|
||||
if self.androidsdkpath is not None:
|
||||
if 'linux' in sys.platform.lower():
|
||||
adbpath = self.androidsdkpath + '/platform-tools/adb'
|
||||
if adbpath is None:
|
||||
raise ADBError('platform')
|
||||
commandstring = [adbpath, 'shell']
|
||||
commandstring.extend(command.split(' '))
|
||||
return commandstring
|
||||
|
||||
def run_adbcmdshell(self, command):
|
||||
commandstring = self._buildcommand(command)
|
||||
return subprocess.Popen(commandstring, stdout=subprocess.PIPE)
|
||||
|
||||
def getDevfile(self):
|
||||
'''
|
||||
Get RILd devicename
|
||||
out: string devicename
|
||||
'''
|
||||
process = self.run_adbcmdshell('getprop rild.libargs')
|
||||
devfile = process.stdout.readline().split(b'/dev/')
|
||||
if len(devfile) >= 2:
|
||||
m = re.match(b'([\d\w]+)', devfile[1])
|
||||
if m is not None:
|
||||
devfile = b'/dev/' + devfile[1].replace(b'\r\n', b'')
|
||||
else:
|
||||
raise ADBError('bad dev string')
|
||||
else:
|
||||
raise ADBError('dev')
|
||||
return devfile.decode("utf-8")
|
||||
|
||||
def _parseCOPS(self, string):
|
||||
'''
|
||||
Parse AT+COPS=? information
|
||||
in(1): string cops returned string
|
||||
out: dict infos
|
||||
'''
|
||||
dict_ = {}
|
||||
rstr = string.replace(b'+COPS: ', b'')
|
||||
for x in rstr.split(b'),'):
|
||||
ysp = x.split(b',')
|
||||
if len(ysp) == 5:
|
||||
mccmnc = ysp[3].decode("utf-8").replace('"','')
|
||||
netname = ysp[1].decode("utf-8").replace('"','')
|
||||
if mccmnc not in dict_:
|
||||
dict_[mccmnc] = netname
|
||||
return dict_
|
||||
|
||||
def getCOPSfromRIL(self):
|
||||
'''
|
||||
Grab PLMN information
|
||||
return: dict PLMN infos
|
||||
'''
|
||||
devfile = self.getDevfile()
|
||||
process = self.run_adbcmdshell("su -c 'echo -e \"AT\r\n\" > %s'" % devfile)
|
||||
process = self.run_adbcmdshell("su -c 'echo -e \"AT+COPS=?\r\n\" > %s && cat %s'" % (devfile,devfile))
|
||||
#process = self.run_adbcmdshell("su -c 'cat %s'" % devfile)
|
||||
stdout_queue = Queue()
|
||||
stdout_reader = AsynchronousFileReader(process.stdout, stdout_queue)
|
||||
stdout_reader.daemon=True
|
||||
stdout_reader.start()
|
||||
stop = False
|
||||
copsList = None
|
||||
countBL = 0
|
||||
while not stdout_reader.eof() and stop is False:
|
||||
while not stdout_queue.empty() and stop is False:
|
||||
try:
|
||||
line = stdout_queue.get()
|
||||
if b'+COPS: ' in line:
|
||||
copsList = self._parseCOPS(line)
|
||||
if len(copsList) > 0:
|
||||
stop = True
|
||||
stdout_reader.stop()
|
||||
process = None
|
||||
return copsList
|
||||
else:
|
||||
if len(line) == 0:
|
||||
countBL += 1
|
||||
if countBL == 10:
|
||||
stop = True
|
||||
except KeyboardInterrupt:
|
||||
stop = True
|
||||
stdout_reader.stop()
|
||||
process.stdout.close()
|
||||
return copsList
|
||||
|
||||
def changePLMN(self, MCCMNC, automode=False):
|
||||
'''
|
||||
Change PLMN using AT commands
|
||||
in(1): string MCCMNC
|
||||
in(2): Bool automode
|
||||
out: process resurl
|
||||
'''
|
||||
mode = 1
|
||||
devfile = self.getDevfile()
|
||||
if automode is True:
|
||||
mode = 0
|
||||
process = self.run_adbcmdshell("su -c 'echo -e \"AT+COPS=%i,2,%s\r\n\" > %s'" % (mode, MCCMNC, devfile))
|
||||
return process
|
||||
|
||||
def changeNetworkTypeGBox(self, type_=1):
|
||||
'''
|
||||
Change Networktype mode using GravityBox
|
||||
in(1): int Networktype mode.
|
||||
out: process result
|
||||
'''
|
||||
process = self.run_adbcmdshell("su -c 'am broadcast -a gravitybox.intent.action.CHANGE_NETWORK_TYPE --ez networkType %i'" % type_)
|
||||
return process
|
||||
|
||||
def changeNetworkType(self, type_=2):
|
||||
'''
|
||||
Change Networktype mode using AT commands
|
||||
in(1): int Networktype mode.
|
||||
2 for Autoselect, 13 for GSM only and 14 for 3G only.
|
||||
out: process result
|
||||
'''
|
||||
devfile = self.getDevfile()
|
||||
process = self.run_adbcmdshell("su -c 'echo -e \"AT^SYSCONFIG=%i,1,1,2\r\n\" > %s'" % (type_, devfile))
|
||||
return process
|
||||
|
||||
def deregister(self):
|
||||
'''
|
||||
Unregister UE from current PLMN
|
||||
out: process result
|
||||
'''
|
||||
devfile = self.getDevfile()
|
||||
process = self.run_adbcmdshell("su -c 'echo -e \"AT+COPS=2\r\n\" > %s'" % devfile)
|
||||
return process
|
||||
|
||||
def airplanemode(self, mode=0):
|
||||
'''
|
||||
UE airplane mode switch
|
||||
in(1): int mode - 1 = ON, 0 = OFF
|
||||
out: process result
|
||||
'''
|
||||
self.run_adbcmdshell("su -c 'settings put global airplane_mode_on %i'" % int(mode))
|
||||
process = self.run_adbcmdshell("su -c 'am broadcast -a android.intent.action.AIRPLANE_MODE'")
|
||||
return process
|
||||
|
||||
def pushsecretcode(self, secretcode):
|
||||
'''
|
||||
Call Android secret codes
|
||||
in(1): String secretcode to call
|
||||
out: process result
|
||||
'''
|
||||
process = self.run_adbcmdshell("su -c 'am broadcast -a android.provider.Telephony.SECRET_CODE -d android_secret_code://%s'" % secretcode)
|
||||
return process
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
class RILd(object):
|
||||
androidsdkpath = None
|
||||
def __init__(self, androidsdkpath=None):
|
||||
self.androidsdkpath = androidsdkpath
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,213 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
from engines.android.generic.ADBshell import *
|
||||
from core.mKB import *
|
||||
from core.mLog import *
|
||||
from utils.colors import *
|
||||
|
||||
class ServiceMode(ADBshell):
|
||||
'''
|
||||
Class abstracting abstracting action to get mobile cells information from ServiceMode
|
||||
'''
|
||||
@Cellslogger
|
||||
def parse4Gcell(self, string):
|
||||
'''
|
||||
Parse 4G cells information
|
||||
in(1): string returned by logcat
|
||||
out: dict infos
|
||||
'''
|
||||
plmn = None
|
||||
tac = None
|
||||
earfcn = None
|
||||
band = None
|
||||
bandwidth = None
|
||||
pci = None
|
||||
cell = {}
|
||||
for s in string.split(b'\r\n'):
|
||||
if b'LTE' in s:
|
||||
if b'Band' in s:
|
||||
band = re.match(b'^.*Band?:?\s?(\d+)', s).group(1)
|
||||
elif b'BAND' in s and b'BW' in s:
|
||||
band, bandwidth = re.match(b'^.*BAND:?\s?(\d+)\sBW:?\s?([\d+\w]+)?\s?\_$', s).groups()
|
||||
if b'MCC-MNC' in s:
|
||||
if b'TAC' in s:
|
||||
plmn, tac = re.match(b'^.*MCC-MNC?\s?:?\s?([\d\-]+)\,?\s?TAC:?\s?(\d+)?\s?\_$', s).groups()
|
||||
elif b'MeG':
|
||||
plmn = re.match(b'^.*MCC-MNC?\s?:?\s?([\d\-\s]+)', s).group(1)
|
||||
if b'Earfcn_dl:' in s:
|
||||
earfcn, pci = re.match(b'^.*Earfcn_dl:?\s?(\d+),?\s?PCI:?\s?(\d+)?\s?\_', s).groups()
|
||||
if b'LTE DL BW' in s:
|
||||
bandwidth = re.match(b'^.*BW?\s?:?\s?([\d\w]+)', s).group(1)
|
||||
if tac is None and b'TAC' in s:
|
||||
tac = re.match(b'^.*TAC?\s?:?\s?([\d]+)', s).group(1)
|
||||
if None not in [plmn, tac, earfcn, band, bandwidth, pci]:
|
||||
tac = tac.decode('utf-8')
|
||||
plmn = plmn.decode('utf-8').replace(' ','')
|
||||
pci = pci.decode('utf-8')
|
||||
bandwidth = bandwidth.decode('utf-8')
|
||||
cid2 = "%s-%i" % (pci, int(earfcn))
|
||||
cell[cid2] = { 'PLMN' : plmn,
|
||||
'band' : int(band),
|
||||
'bandwidth' : bandwidth,
|
||||
'eARFCN': int(earfcn),
|
||||
'PCI' : pci,
|
||||
'TAC' : tac,
|
||||
'type' : '4G',
|
||||
}
|
||||
return cell
|
||||
|
||||
@Cellslogger
|
||||
def parse3Gcell_sgs3like(self, string):
|
||||
'''
|
||||
Parse 3G cells information
|
||||
in(1): string returned by logcat
|
||||
out: dict infos
|
||||
'''
|
||||
plmn = None
|
||||
cid = None
|
||||
tx = None
|
||||
rx = None
|
||||
band = None
|
||||
cell = {}
|
||||
for s in string.split(b'\r\n'):
|
||||
if b'Band' in s:
|
||||
band = re.match(b'^.*Band?:?\s?(\d+)', s).group(1)
|
||||
if b'Reg PLMN' in s:
|
||||
plmn = re.match(b'^.*Reg PLMN?\s?([\d\-]+)', s).group(1)
|
||||
if b'CELL_ID' in s:
|
||||
cid = re.match(b'^.*CELL_ID:?\s?(\S+)', s).group(1)
|
||||
if b'CH DL:' in s:
|
||||
tx = re.match(b'^.*CH DL:?\s?(\d+)', s).group(1)
|
||||
if b', UL:' in s:
|
||||
rx = re.match(b'^.*\,\sUL:?\s?(\d+)', s).group(1)
|
||||
if None not in [tx, rx, cid, plmn, band]:
|
||||
cid = cid.decode('utf-8').replace('_','')
|
||||
plmn = plmn.decode("utf-8").replace(' ', '')
|
||||
cid2 = "%s-%i" % (cid, int(rx))
|
||||
cell[cid2] = { 'PLMN' : plmn,
|
||||
'TX' : int(tx),
|
||||
'RX' : int(rx),
|
||||
'band': int(band),
|
||||
'type' : '3G',
|
||||
}
|
||||
return cell
|
||||
|
||||
@Cellslogger
|
||||
def parse3Gcell(self, string):
|
||||
'''
|
||||
Parse 3G cells information SGS3 like structs
|
||||
in(1): string returned by logcat
|
||||
out: dict infos
|
||||
'''
|
||||
plmn = None
|
||||
cid = None
|
||||
tx = None
|
||||
rx = None
|
||||
band = None
|
||||
cell = {}
|
||||
for s in string.split(b'\r\n'):
|
||||
if b'Band' in s:
|
||||
band = re.match(b'^.*Band?:?\s?(\d+)', s).group(1)
|
||||
if b'PLMN:' in s:
|
||||
plmn = re.match(b'^.*PLMN:?\s?([\d\-]+)?\s?\_$', s).group(1)
|
||||
elif b'MCC-MNC :' in s:
|
||||
plmn = re.match(b'^.*MCC-MNC\s:?\s?([\d\-\s]+)?\s?\_$', s).group(1)
|
||||
if b'CID:' in s:
|
||||
cid = re.match(b'^.*CID:?\s?(\S+)?\s?_$', s).group(1)
|
||||
if b' TX:' in s:
|
||||
tx = re.match(b'^.*TX:?\s?(\d+)', s).group(1)
|
||||
if b' RX:' in s:
|
||||
rx = re.match(b'^.*RX:?\s?(\d+)', s).group(1)
|
||||
if None not in [tx, rx, cid, plmn, band]:
|
||||
cid = cid.decode('utf-8')
|
||||
plmn = plmn.decode("utf-8").replace(' ', '')
|
||||
cid2 = "%s-%i" % (cid, int(rx))
|
||||
cell[cid2] = { 'PLMN' : plmn,
|
||||
'TX' : int(tx),
|
||||
'RX' : int(rx),
|
||||
'band': int(band),
|
||||
'type' : '3G',
|
||||
}
|
||||
return cell
|
||||
|
||||
@Cellslogger
|
||||
def parse2Gcell(self, string):
|
||||
'''
|
||||
Parse 2G cells information SGS5 like structs
|
||||
in(1): string returned by logcat
|
||||
out: dict infos
|
||||
'''
|
||||
plmn = None
|
||||
cid = None
|
||||
arfcn = None
|
||||
cell = {}
|
||||
for s in string.split(b'\r\n'):
|
||||
if b'PLMN:' in s:
|
||||
plmn = re.match(b'^.*PLMN:?\s?([\d\-]+)?\s?\_$', s).group(1)
|
||||
elif b'MCC-MNC :' in s:
|
||||
plmn = re.match(b'^.*MCC-MNC\s:?\s?([\d\-\s]+)?\s?\_$', s).group(1)
|
||||
if b'CID:' in s:
|
||||
cid = re.match(b'^.*CID:?\s?(\S+)?\s?_$', s).group(1)
|
||||
if b' Tra:' in s:
|
||||
arfcn = re.match(b'^.*Tra:?\s?(\d+)', s).group(1)
|
||||
if None not in [arfcn, cid, plmn]:
|
||||
cid = cid.decode('utf-8')
|
||||
plmn = plmn.decode("utf-8").replace(' ', '')
|
||||
cid2 = "%s-%i" % (cid, int(arfcn))
|
||||
cell[cid2] = { 'PLMN' : plmn,
|
||||
'arfcn' : int(arfcn),
|
||||
'type' : '2G',
|
||||
'cid' : cid,
|
||||
}
|
||||
return cell
|
||||
|
||||
|
||||
def grablogcat(self):
|
||||
'''
|
||||
Grab ServiceMode information from logcat
|
||||
out: dict ParsedCell
|
||||
'''
|
||||
process = self.run_adbcmdshell('logcat -s ServiceModeApp_RIL:I,ServiceMode:I,ModemServiceMode:I')
|
||||
stdout_queue = Queue()
|
||||
stdout_reader = AsynchronousFileReader(process.stdout, stdout_queue)
|
||||
stdout_reader.daemon=True
|
||||
stdout_reader.start()
|
||||
stop = False
|
||||
capture = b''
|
||||
while not stdout_reader.eof() and stop is False:
|
||||
while not stdout_queue.empty() and stop is False:
|
||||
try:
|
||||
line = stdout_queue.get()
|
||||
if b'Update!' in line:
|
||||
if b'LTE RRC:' in capture:
|
||||
self.parse4Gcell(capture)
|
||||
elif b'UMTS :' in capture:
|
||||
self.parse3Gcell_sgs3like(capture)
|
||||
if b'GSM' in capture:
|
||||
self.parse2Gcell(capture)
|
||||
else:
|
||||
self.parse3Gcell(capture)
|
||||
capture = b''
|
||||
capture += line
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
stop = True
|
||||
stdout_reader.stop()
|
||||
stdout_reader.stop()
|
||||
process.stdout.close()
|
||||
|
||||
def output2xml():
|
||||
from xml.dom.minidom import Document
|
||||
kb = mKB()
|
||||
root = doc.createElement('moncells')
|
||||
for k,v in kb.data['SM_cells'].items():
|
||||
cell = doc.createElement('cell')
|
||||
root.appendChild(cell)
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
from core.mLog import Cellslogger
|
||||
from core.mKB import *
|
||||
|
||||
class xgoldmod(object):
|
||||
@Cellslogger
|
||||
def go2logs(self, cell):
|
||||
return cell
|
||||
|
||||
def parseFifo(self):
|
||||
kb = mKB()
|
||||
FIFO = kb.config['file']
|
||||
if 'SM_cells' not in kb.data:
|
||||
kb.data['SM_cells'] = {}
|
||||
while True:
|
||||
with open(FIFO) as fifo:
|
||||
while True:
|
||||
data = fifo.read()
|
||||
if len(data) == 0:
|
||||
break
|
||||
infos = data.split(':')[1]
|
||||
isplit = infos.split(';')
|
||||
tmpcell = {}
|
||||
tmpcell2 = {}
|
||||
for cell in isplit:
|
||||
pcell = cell.split('=')
|
||||
tmpcell[pcell[0]] = pcell[1]
|
||||
cid = tmpcell['CID'] + '-' + tmpcell['DL_UARFCN']
|
||||
tmpcell2[cid] = { 'PLMN' : tmpcell['PLMN'],
|
||||
'RAC' : tmpcell['RAC'],
|
||||
'LAC' : tmpcell['LAC'],
|
||||
'type' : '3G',
|
||||
'RX' : int(tmpcell['DL_UARFCN']),
|
||||
'TX' : int(tmpcell['UL_UARFCN'].split('\0')[0]),
|
||||
}
|
||||
self.go2logs(tmpcell2)
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import print_function
|
||||
import serial
|
||||
|
||||
class AT(object):
|
||||
tty_int = None
|
||||
def __init__(self, tty_path):
|
||||
self.tty_int = serial.Serial(tty_path, 115200)
|
||||
|
||||
def _parseCOPS(self, string):
|
||||
'''
|
||||
Parse AT+COPS=? information
|
||||
in(1): string cops returned string
|
||||
out: dict infos
|
||||
'''
|
||||
dict_ = {}
|
||||
rstr = string.replace(b'+COPS: ', b'')
|
||||
for x in rstr.split(b'),'):
|
||||
ysp = x.split(b',')
|
||||
if len(ysp) >= 5:
|
||||
mccmnc = ysp[3].decode("utf-8").replace('"','')
|
||||
netname = ysp[1].decode("utf-8").replace('"','')
|
||||
if mccmnc not in dict_:
|
||||
dict_[mccmnc] = netname
|
||||
return dict_
|
||||
|
||||
def getCOPS(self):
|
||||
tty_int = self.tty_int
|
||||
tty_int.write(b'AT+COPS=?\r\n')
|
||||
tty_int.readline() # command sent
|
||||
result = tty_int.readline()
|
||||
#tty_int.readline()
|
||||
return self._parseCOPS(result)
|
||||
|
||||
def changePLMN(self, MCCMNC, automode=False):
|
||||
mode = 1
|
||||
tty_int = self.tty_int
|
||||
if automode is True:
|
||||
mode = 0
|
||||
tty_int.write(b"AT+COPS=%i,2,\"%s\"\r\n" % (mode, MCCMNC.encode('utf-8')))
|
||||
|
||||
def unregister(self):
|
||||
tty_int = self.tty_int
|
||||
tty_int.write(b"AT+COPS=2\r\n")
|
||||
|
||||
def changeNetworkType(self, type_=2):
|
||||
'''
|
||||
Change Networktype mode using AT commands
|
||||
in(1): int Networktype mode.
|
||||
2 for Autoselect, 13 for GSM only and 14 for 3G only.
|
||||
out: process result
|
||||
'''
|
||||
tty_int = self.tty_int
|
||||
tty_int.write(b"AT^SYSCONFIG=%i,1,1,2\r\n")
|
||||
|
||||
if __name__ == "__main__":
|
||||
ser = AT('/dev/ttyACM0')
|
||||
print (ser.getCOPS())
|
||||
ser.changePLMN(b'20801')
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
from utils.logprocess import *
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description='Mobile network mapping tool with cheap equipments')
|
||||
parser.add_argument('-m', '--module', dest='module', required=False, default='servicemode',
|
||||
help='Module to use (e.g: "servicemode" by default)')
|
||||
parser.add_argument('-n', '--networks', dest='networks', required=False, default=None,
|
||||
help='Networks in MCCMNC format splitted with commas')
|
||||
parser.add_argument('-o', '--cached_operator', dest='operators', required=False, default=False, action='store_true',
|
||||
help='Use operator in cache to speed up the passive scan')
|
||||
parser.add_argument('-s', '--sdk', dest='androidsdk', required=False, default='/opt/Android',
|
||||
help='Android SDK path')
|
||||
parser.add_argument('-a', '--at', dest='atmode', required=False, default=None,
|
||||
help='AT access mode. If host put something like "/dev/ttyUSBxx. By default it uses ADB."')
|
||||
parser.add_argument('-f', '--file', dest='file', required=False, default=None,
|
||||
help='File to parse. For the moment it could be used in combination with AT mode host.')
|
||||
args = parser.parse_args()
|
||||
sm = ADBshell()
|
||||
kb = mKB()
|
||||
kb.config['androidsdk'] = args.androidsdk
|
||||
sm.androidsdkpath = args.androidsdk
|
||||
if args.file is not None:
|
||||
kb.config['file'] = args.file
|
||||
if args.module == "xgoldmod":
|
||||
startXgoldmodCollect()
|
||||
else:
|
||||
startServiceModeCollect()
|
||||
cops = None
|
||||
if args.networks is not None:
|
||||
printInfo('=> Manual MCC/MNC processing...')
|
||||
cops = processManualMCCMN(args.networks)
|
||||
else:
|
||||
printInfo('=> Requesting a list of MCC/MNC. Please wait, it may take a while...')
|
||||
operators = load_operators()
|
||||
if args.operators is True:
|
||||
print (bcolors.WARNING+"Found %i operators in cache, you choose to reuse them." % len(operators) + bcolors.ENDC)
|
||||
cops = operators
|
||||
if cops is None:
|
||||
if args.atmode is None:
|
||||
cops = sm.getCOPSfromRIL()
|
||||
else:
|
||||
at = AT(args.atmode)
|
||||
cops = at.getCOPS()
|
||||
saveMCCMNC(cops)
|
||||
if cops is None:
|
||||
sys.exit("Problem with AT+COPS=? anwser. Please reboot the phone and try again")
|
||||
else:
|
||||
print (bcolors.WARNING+"Found %i operator(s)" % len(cops))
|
||||
print (cops, bcolors.ENDC)
|
||||
operators = [x for x,y in cops.items()]
|
||||
if args.atmode is None:
|
||||
processOperatorADB(operators)
|
||||
else:
|
||||
kb.config['tty_file'] = args.atmode
|
||||
processOperatorAT(operators)
|
|
@ -0,0 +1 @@
|
|||
serial
|
|
@ -0,0 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
|
@ -0,0 +1,16 @@
|
|||
# temp colors taken from some stackoverflow post I guess
|
||||
class bcolors:
|
||||
HEADER = '\033[95m'
|
||||
OKBLUE = '\033[94m'
|
||||
OKGREEN = '\033[92m'
|
||||
WARNING = '\033[93m'
|
||||
FAIL = '\033[91m'
|
||||
ENDC = '\033[0m'
|
||||
|
||||
def disable(self):
|
||||
self.HEADER = ''
|
||||
self.OKBLUE = ''
|
||||
self.OKGREEN = ''
|
||||
self.WARNING = ''
|
||||
self.FAIL = ''
|
||||
self.ENDC = ''
|
|
@ -0,0 +1,486 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
#####################################
|
||||
# UARFCN and EARFCN Calculator
|
||||
#####################################
|
||||
|
||||
##
|
||||
# Tables
|
||||
#
|
||||
table_earfcn = {
|
||||
1 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 0,
|
||||
'DL_range' : (0,599),
|
||||
'FUL_Low' : 1920,
|
||||
'NUL_Offset' : 18000,
|
||||
'UP_range' : (1800,18599),
|
||||
},
|
||||
2 : { 'FDL_Low' : 1930,
|
||||
'NDL_Offset' : 600,
|
||||
'DL_range' : (600,1199),
|
||||
'FUL_Low' : 1850,
|
||||
'NUL_Offset' : 18600,
|
||||
'UP_range' : (18600,19199),
|
||||
},
|
||||
3 : { 'FDL_Low' : 1805,
|
||||
'NDL_Offset' : 1200,
|
||||
'DL_range' : (1200,1949),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 19200,
|
||||
'UP_range' : (19200,19949),
|
||||
},
|
||||
4 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 1950,
|
||||
'DL_range' : (1950,2399),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 19950,
|
||||
'UP_range' : (19950,20399),
|
||||
},
|
||||
5 : { 'FDL_Low' : 869,
|
||||
'NDL_Offset' : 2400,
|
||||
'DL_range' : (2400,2649),
|
||||
'FUL_Low' : 824,
|
||||
'NUL_Offset' : 20400,
|
||||
'UP_range' : (20400,20649),
|
||||
},
|
||||
6 : { 'FDL_Low' : 875,
|
||||
'NDL_Offset' : 2650,
|
||||
'DL_range' : (2650,2749),
|
||||
'FUL_Low' : 830,
|
||||
'NUL_Offset' : 20650,
|
||||
'UP_range' : (20650,20749),
|
||||
},
|
||||
7 : { 'FDL_Low' : 2620,
|
||||
'NDL_Offset' : 2750,
|
||||
'DL_range' : (2750,3449),
|
||||
'FUL_Low' : 2500,
|
||||
'NUL_Offset' : 20750,
|
||||
'UP_range' : (20750,21449),
|
||||
},
|
||||
8 : { 'FDL_Low' : 925,
|
||||
'NDL_Offset' : 3450,
|
||||
'DL_range' : (3450,3799),
|
||||
'FUL_Low' : 880,
|
||||
'NUL_Offset' : 21450,
|
||||
'UP_range' : (21450,21799),
|
||||
},
|
||||
9 : { 'FDL_Low' : 1844.9,
|
||||
'NDL_Offset' : 3800,
|
||||
'DL_range' : (3800,4149),
|
||||
'FUL_Low' : 1749.9,
|
||||
'NUL_Offset' : 21800,
|
||||
'UP_range' : (21800,22149),
|
||||
},
|
||||
10 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 4150,
|
||||
'DL_range' : (4150,4749),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 22150,
|
||||
'UP_range' : (22150,22749),
|
||||
},
|
||||
11 : { 'FDL_Low' : 1475.9,
|
||||
'NDL_Offset' : 4750,
|
||||
'DL_range' : (4750,4949),
|
||||
'FUL_Low' : 1427.9,
|
||||
'NUL_Offset' : 22750,
|
||||
'UP_range' : (22750,22949),
|
||||
},
|
||||
12 : { 'FDL_Low' : 729,
|
||||
'NDL_Offset' : 5010,
|
||||
'DL_range' : (5010,5179),
|
||||
'FUL_Low' : 699,
|
||||
'NUL_Offset' : 23010,
|
||||
'UP_range' : (23010,23179),
|
||||
},
|
||||
13 : { 'FDL_Low' : 746,
|
||||
'NDL_Offset' : 5180,
|
||||
'DL_range' : (5180,5279),
|
||||
'FUL_Low' : 777,
|
||||
'NUL_Offset' : 23180,
|
||||
'UP_range' : (23180,23279),
|
||||
},
|
||||
14 : { 'FDL_Low' : 758,
|
||||
'NDL_Offset' : 5280,
|
||||
'DL_range' : (5280,5379),
|
||||
'FUL_Low' : 788,
|
||||
'NUL_Offset' : 23280,
|
||||
'UP_range' : (23280,23379),
|
||||
},
|
||||
17 : { 'FDL_Low' : 734,
|
||||
'NDL_Offset' : 5730,
|
||||
'DL_range' : (5730,5849),
|
||||
'FUL_Low' : 704,
|
||||
'NUL_Offset' : 23730,
|
||||
'UP_range' : (23730,23849),
|
||||
},
|
||||
18 : { 'FDL_Low' : 860,
|
||||
'NDL_Offset' : 5850,
|
||||
'DL_range' : (5850,5999),
|
||||
'FUL_Low' : 815,
|
||||
'NUL_Offset' : 23850,
|
||||
'UP_range' : (23850,23999),
|
||||
},
|
||||
19 : { 'FDL_Low' : 875,
|
||||
'NDL_Offset' : 6000,
|
||||
'DL_range' : (6000,6149),
|
||||
'FUL_Low' : 830,
|
||||
'NUL_Offset' : 24000,
|
||||
'UP_range' : (24000,24149),
|
||||
},
|
||||
20 : { 'FDL_Low' : 791,
|
||||
'NDL_Offset' : 6150,
|
||||
'DL_range' : (6150,6449),
|
||||
'FUL_Low' : 832,
|
||||
'NUL_Offset' : 24150,
|
||||
'UP_range' : (24150,24449),
|
||||
},
|
||||
21 : { 'FDL_Low' : 1495.9,
|
||||
'NDL_Offset' : 6450,
|
||||
'DL_range' : (6450,6599),
|
||||
'FUL_Low' : 1447.9,
|
||||
'NUL_Offset' : 24450,
|
||||
'UP_range' : (24450,24599),
|
||||
},
|
||||
22 : { 'FDL_Low' : 3510,
|
||||
'NDL_Offset' : 6600,
|
||||
'DL_range' : (6600,7399),
|
||||
'FUL_Low' : 3410,
|
||||
'NUL_Offset' : 24600,
|
||||
'UP_range' : (24600,25399),
|
||||
},
|
||||
23 : { 'FDL_Low' : 2180,
|
||||
'NDL_Offset' : 7500,
|
||||
'DL_range' : (7500,7699),
|
||||
'FUL_Low' : 2000,
|
||||
'NUL_Offset' : 25500,
|
||||
'UP_range' : (25500,25699),
|
||||
},
|
||||
24 : { 'FDL_Low' : 1525,
|
||||
'NDL_Offset' : 7700,
|
||||
'DL_range' : (7700,8039),
|
||||
'FUL_Low' : 1626.5,
|
||||
'NUL_Offset' : 25700,
|
||||
'UP_range' : (25700,26039),
|
||||
},
|
||||
25 : { 'FDL_Low' : 1930,
|
||||
'NDL_Offset' : 8040,
|
||||
'DL_range' : (8040,8689),
|
||||
'FUL_Low' : 1850,
|
||||
'NUL_Offset' : 26040,
|
||||
'UP_range' : (26040,26689),
|
||||
},
|
||||
26 : { 'FDL_Low' : 859,
|
||||
'NDL_Offset' : 8690,
|
||||
'DL_range' : (8690,9039),
|
||||
'FUL_Low' : 814,
|
||||
'NUL_Offset' : 26690,
|
||||
'UP_range' : (26690,27039),
|
||||
},
|
||||
27 : { 'FDL_Low' : 852,
|
||||
'NDL_Offset' : 9040,
|
||||
'DL_range' : (9040,9209),
|
||||
'FUL_Low' : 807,
|
||||
'NUL_Offset' : 27040,
|
||||
'UP_range' : (27040,27209),
|
||||
},
|
||||
28 : { 'FDL_Low' : 758,
|
||||
'NDL_Offset' : 9210,
|
||||
'DL_range' : (9210,9659),
|
||||
'FUL_Low' : 703,
|
||||
'NUL_Offset' : 27210,
|
||||
'UP_range' : (27210,27659),
|
||||
},
|
||||
30 : { 'FDL_Low' : 2350,
|
||||
'NDL_Offset' : 9770,
|
||||
'DL_range' : (9770,9869),
|
||||
'FUL_Low' : 2305,
|
||||
'NUL_Offset' : 27660,
|
||||
'UP_range' : (27660,27759),
|
||||
},
|
||||
31 : { 'FDL_Low' : 462.5,
|
||||
'NDL_Offset' : 9870,
|
||||
'DL_range' : (9870,9919),
|
||||
'FUL_Low' : 452.5,
|
||||
'NUL_Offset' : 27760,
|
||||
'UP_range' : (27760,27809),
|
||||
},
|
||||
65 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 65536,
|
||||
'DL_range' : (65536,66435),
|
||||
'FUL_Low' : 1920,
|
||||
'NUL_Offset' : 131072,
|
||||
'UP_range' : (131072,131971),
|
||||
},
|
||||
66 : { 'FDL_Low' : 2110,
|
||||
'NDL_Offset' : 66436,
|
||||
'DL_range' : (66436,67335),
|
||||
'FUL_Low' : 1710,
|
||||
'NUL_Offset' : 131972,
|
||||
'UP_range' : (131972,132671),
|
||||
},
|
||||
68 : { 'FDL_Low' : 753,
|
||||
'NDL_Offset' : 67536,
|
||||
'DL_range' : (67536,67835),
|
||||
'FUL_Low' : 698,
|
||||
'NUL_Offset' : 132672,
|
||||
'UP_range' : (132672,132971),
|
||||
},
|
||||
70 : { 'FDL_Low' : 1995,
|
||||
'NDL_Offset' : 68336,
|
||||
'DL_range' : (68336,68585),
|
||||
'FUL_Low' : 1695,
|
||||
'NUL_Offset' : 132972,
|
||||
'UP_range' : (132972,133121),
|
||||
},
|
||||
71 : { 'FDL_Low' : 617,
|
||||
'NDL_Offset' : 68586,
|
||||
'DL_range' : (68586,68935),
|
||||
'FUL_Low' : 663,
|
||||
'NUL_Offset' : 133122,
|
||||
'UP_range' : (133122,133471),
|
||||
},
|
||||
72 : { 'FDL_Low' : 461,
|
||||
'NDL_Offset' : 68936,
|
||||
'DL_range' : (68936,68985),
|
||||
'FUL_Low' : 451,
|
||||
'NUL_Offset' : 133472,
|
||||
'UP_range' : (133472,133521),
|
||||
},
|
||||
73 : { 'FDL_Low' : 460,
|
||||
'NDL_Offset' : 68986,
|
||||
'DL_range' : (68986,69465),
|
||||
'FUL_Low' : 450,
|
||||
'NUL_Offset' : 133522,
|
||||
'UP_range' : (133522,133571),
|
||||
},
|
||||
74 : { 'FDL_Low' : 1475,
|
||||
'NDL_Offset' : 69036,
|
||||
'DL_range' : (69036,69035),
|
||||
'FUL_Low' : 1427,
|
||||
'NUL_Offset' : 133572,
|
||||
'UP_range' : (133572,134001),
|
||||
},
|
||||
85 : { 'FDL_Low' : 728,
|
||||
'NDL_Offset' : 70366,
|
||||
'DL_range' : (70366,70545),
|
||||
'FUL_Low' : 698,
|
||||
'NUL_Offset' : 134002,
|
||||
'UP_range' : (134002,134181),
|
||||
},
|
||||
}
|
||||
|
||||
table_uarfcn = {
|
||||
1 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 2112.4,
|
||||
'DL_range' : (10562,10838),
|
||||
'FUL_Low' : 1922.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (9612,9888),
|
||||
},
|
||||
2 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 1932.4,
|
||||
'DL_range' : (9662,9938),
|
||||
'FUL_Low' : 1852.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (9262,9538),
|
||||
},
|
||||
3 : { 'FDL_Offset' : 1525,
|
||||
'FDL_Low' : 1712.4,
|
||||
'DL_range' : (937,1288),
|
||||
'FUL_Low' : 1807.4,
|
||||
'NUL_Offset' : 1575,
|
||||
'UP_range' : (1162,1513),
|
||||
},
|
||||
4 : { 'FDL_Offset' : 1805,
|
||||
'FDL_Low' : 2112.4,
|
||||
'DL_range' : (1537,1738),
|
||||
'FUL_Low' : 1712.4,
|
||||
'NUL_Offset' : 1450,
|
||||
'UP_range' : (1312,1513),
|
||||
},
|
||||
5 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 871.4,
|
||||
'DL_range' : (4357,4458),
|
||||
'FUL_Low' : 826.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (4132,4233),
|
||||
},
|
||||
6 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 877.4,
|
||||
'DL_range' : (4387,4413),
|
||||
'FUL_Low' : 832.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (4162,4188),
|
||||
},
|
||||
7 : { 'FDL_Offset' : 2175,
|
||||
'FDL_Low' : 2622.4,
|
||||
'DL_range' : (2237,2563),
|
||||
'FUL_Low' : 2502.4,
|
||||
'NUL_Offset' : 2100,
|
||||
'UP_range' : (2012,2338),
|
||||
},
|
||||
8 : { 'FDL_Offset' : 340,
|
||||
'FDL_Low' : 927.4,
|
||||
'DL_range' : (2937,3088),
|
||||
'FUL_Low' : 882.4,
|
||||
'NUL_Offset' : 340,
|
||||
'UP_range' : (2712,2863),
|
||||
},
|
||||
9 : { 'FDL_Offset' : 0,
|
||||
'FDL_Low' : 1847.4,
|
||||
'DL_range' : (9237,93878),
|
||||
'FUL_Low' : 1752.4,
|
||||
'NUL_Offset' : 0,
|
||||
'UP_range' : (8762,8912),
|
||||
},
|
||||
10 : { 'FDL_Offset' : 1490,
|
||||
'FDL_Low' : 2112.4,
|
||||
'DL_range' : (3112,3388),
|
||||
'FUL_Low' : 1712.4,
|
||||
'NUL_Offset' : 1135,
|
||||
'UP_range' : (2887,3163),
|
||||
},
|
||||
11 : { 'FDL_Offset' : 736,
|
||||
'FDL_Low' : 1478.4,
|
||||
'DL_range' : (3712,3812),
|
||||
'FUL_Low' : 1430.4,
|
||||
'NUL_Offset' : 733,
|
||||
'UP_range' : (3487,3587),
|
||||
},
|
||||
12 : { 'FDL_Offset' : -37,
|
||||
'FDL_Low' : 730.4,
|
||||
'DL_range' : (3837,3903),
|
||||
'FUL_Low' : 700.4,
|
||||
'NUL_Offset' : -22,
|
||||
'UP_range' : (3612,3678),
|
||||
},
|
||||
13 : { 'FDL_Offset' : -55,
|
||||
'FDL_Low' : 748.4,
|
||||
'DL_range' : (4017,4043),
|
||||
'FUL_Low' : 779.4,
|
||||
'NUL_Offset' : 21,
|
||||
'UP_range' : (3792,3818),
|
||||
},
|
||||
14 : { 'FDL_Offset' : -63,
|
||||
'FDL_Low' : 760.4,
|
||||
'DL_range' : (4117,4143),
|
||||
'FUL_Low' : 790.4,
|
||||
'NUL_Offset' : 12,
|
||||
'UP_range' : (3892,3918),
|
||||
},
|
||||
19 : { 'FDL_Offset' : 735,
|
||||
'FDL_Low' : 877.4,
|
||||
'DL_range' : (712,763),
|
||||
'FUL_Low' : 832.4,
|
||||
'NUL_Offset' : 770,
|
||||
'UP_range' : (312,363),
|
||||
},
|
||||
20 : { 'FDL_Offset' : -109,
|
||||
'FDL_Low' : 793.4,
|
||||
'DL_range' : (4512,4638),
|
||||
'FUL_Low' : 834.4,
|
||||
'NUL_Offset' : -23,
|
||||
'UP_range' : (4287,4413),
|
||||
},
|
||||
21 : { 'FDL_Offset' : 1326,
|
||||
'FDL_Low' : 1498.4,
|
||||
'DL_range' : (862,912),
|
||||
'FUL_Low' : 1450.4,
|
||||
'NUL_Offset' : 1358,
|
||||
'UP_range' : (462,512),
|
||||
},
|
||||
22 : { 'FDL_Offset' : 2580,
|
||||
'FDL_Low' : 3512.4,
|
||||
'DL_range' : (4662,5038),
|
||||
'FUL_Low' : 3412.4,
|
||||
'NUL_Offset' : 2525,
|
||||
'UP_range' : (4437,4813),
|
||||
},
|
||||
25 : { 'FDL_Offset' : 910,
|
||||
'FDL_Low' : 1932.4,
|
||||
'DL_range' : (5112,5413),
|
||||
'FUL_Low' : 1852.4,
|
||||
'NUL_Offset' : 875,
|
||||
'UP_range' : (4887,5188),
|
||||
},
|
||||
26 : { 'FDL_Offset' : -291,
|
||||
'FDL_Low' : 1932.4,
|
||||
'DL_range' : (5762,5913),
|
||||
'FUL_Low' : 1852.4,
|
||||
'NUL_Offset' : -291,
|
||||
'UP_range' : (5537,5688),
|
||||
},
|
||||
}
|
||||
|
||||
##
|
||||
# Functions
|
||||
#
|
||||
|
||||
def uarfcn2freq(band, dl_uarfcn=None, ul_uarfcn=None):
|
||||
'''
|
||||
in(1): int band index,
|
||||
in(2): int Downling UARFCN index,
|
||||
in(3): int Uplink UARFCN index,
|
||||
out: tuple (float downlink_freq, float uplink_freq)
|
||||
'''
|
||||
duplex_spacing = abs(table_uarfcn[band]['FDL_Low']-table_uarfcn[band]['FUL_Low'])
|
||||
FDL_Offset = table_uarfcn[band]['FDL_Offset']
|
||||
FUL_Offset = table_uarfcn[band]['NUL_Offset']
|
||||
downlink_freq = uplink_freq = None
|
||||
if dl_uarfcn is not None:
|
||||
downlink_freq = FDL_Offset + 0.2 * dl_uarfcn
|
||||
if ul_uarfcn is not None:
|
||||
uplink_freq = FUL_Offset + 0.2 * ul_uarfcn
|
||||
if downlink_freq is not None and uplink_freq is None:
|
||||
uplink_freq = downlink_freq - duplex_spacing
|
||||
elif downlink_freq is None and uplink_freq is not None:
|
||||
downlink_freq = downlink_freq + duplex_spacing
|
||||
return (downlink_freq, uplink_freq)
|
||||
|
||||
def earfcn2freq(band, dl_earfcn=None, ul_earfcn=None):
|
||||
'''
|
||||
in(1): int band index,
|
||||
in(2): int Downling EARFCN index,
|
||||
in(3): int Uplink EARFCN index,
|
||||
out: tuple (float downlink_freq, float uplink_freq)
|
||||
'''
|
||||
NDL_Offset = table_earfcn[band]['NDL_Offset']
|
||||
NUL_Offset = table_earfcn[band]['NUL_Offset']
|
||||
duplex_spacing = abs(table_earfcn[band]['FDL_Low']-table_earfcn[band]['FUL_Low'])
|
||||
FDL_Low = table_earfcn[band]['FDL_Low']
|
||||
FUL_Low = table_earfcn[band]['FUL_Low']
|
||||
downlink_freq = uplink_freq = None
|
||||
if dl_earfcn is not None:
|
||||
downlink_freq = FDL_Low + 0.1 * (dl_earfcn-NDL_Offset)
|
||||
if ul_earfcn is not None:
|
||||
uplink_freq = FUL_Low + 0.1 * (ul_earfcn-NUL_Offset)
|
||||
if downlink_freq is not None and uplink_freq is None:
|
||||
uplink_freq = downlink_freq - duplex_spacing
|
||||
elif downlink_freq is None and uplink_freq is not None:
|
||||
downlink_freq = downlink_freq + duplex_spacing
|
||||
return (downlink_freq, uplink_freq)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("nettype", type=int, help="select network type: 1 for 3G, and 2 for 4G")
|
||||
parser.add_argument("band", type=int, help="Band index")
|
||||
parser.add_argument("downlink", type=int, help="Downlink U/E-ARFCN")
|
||||
parser.add_argument("--uplink", type=int, help="Uplink U/E-ARFCN")
|
||||
args = parser.parse_args()
|
||||
if args.nettype == 1:
|
||||
ret = uarfcn2freq(args.band, args.downlink, args.uplink)
|
||||
elif args.nettype == 2:
|
||||
ret = earfcn2freq(args.band, args.downlink, args.uplink)
|
||||
print ("[+] Selected Downlink ARFCN %i (band %i)" % (args.downlink, args.band))
|
||||
print ("Downlink: %f MHz and Uplink: %f MHz" % (ret[0],ret[1]))
|
|
@ -0,0 +1,142 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ----------------------------------------------------------------------------
|
||||
# "THE BEER-WARE LICENSE" (Revision 42):
|
||||
# <sebastien.dudek(<@T>)synacktiv.com> wrote this file. As long as you retain this notice you
|
||||
# can do whatever you want with this stuff. If we meet some day, and you think
|
||||
# this stuff is worth it, you can buy me a beer in return FlUxIuS ;)
|
||||
|
||||
from __future__ import print_function
|
||||
from engines.android.generic.ADBshell import *
|
||||
from engines.android.samsung.ServiceMode import *
|
||||
from engines.host.diag.xgoldmod import *
|
||||
from engines.host.serial.AT import AT
|
||||
from utils.colors import *
|
||||
from core.mKB import *
|
||||
import time
|
||||
from threading import Thread
|
||||
import argparse
|
||||
import json
|
||||
|
||||
kb = mKB()
|
||||
|
||||
def statesmv(func, msg=None, wait=10, arg=None):
|
||||
if msg is not None:
|
||||
print (bcolors.OKBLUE+msg+bcolors.ENDC)
|
||||
if arg is not None:
|
||||
func(arg)
|
||||
else:
|
||||
func()
|
||||
time.sleep(wait)
|
||||
|
||||
def bringTestMode():
|
||||
sm = ADBshell()
|
||||
sm.androidsdkpath = mKB.config['androidsdk']
|
||||
statesmv(sm.pushsecretcode, arg='4636', wait=2)
|
||||
|
||||
def bringServiceMode():
|
||||
sm = ADBshell()
|
||||
sm.androidsdkpath = mKB.config['androidsdk']
|
||||
statesmv(sm.pushsecretcode, arg='0011', wait=2)
|
||||
|
||||
def startXgoldmodCollect():
|
||||
xg = xgoldmod()
|
||||
th = Thread(target=xg.parseFifo)
|
||||
th.daemon = True
|
||||
th.start()
|
||||
|
||||
def startServiceModeCollect():
|
||||
sm = ServiceMode()
|
||||
sm.androidsdkpath = mKB.config['androidsdk']
|
||||
bringTestMode()
|
||||
bringServiceMode()
|
||||
th = Thread(target=sm.grablogcat)
|
||||
th.daemon = True
|
||||
th.start()
|
||||
|
||||
def printInfo(string):
|
||||
print (bcolors.OKBLUE+string+bcolors.ENDC)
|
||||
|
||||
def saveCells(obj):
|
||||
import time
|
||||
jscells = json.dumps(obj, indent=4, sort_keys=True)
|
||||
name = "cells_%d.json" % float(time.time())
|
||||
f = open("%s" % name, 'w+')
|
||||
f.write(jscells)
|
||||
f.close()
|
||||
printInfo("[+] Cells save as %s" % name)
|
||||
|
||||
|
||||
def processOperatorAT(operators):
|
||||
at_tty = kb.config['tty_file']
|
||||
at = AT(at_tty)
|
||||
state = True
|
||||
while state:
|
||||
try:
|
||||
for code in operators:
|
||||
statesmv(at.unregister,
|
||||
"[+] Unregistered from current PLMN")
|
||||
statesmv(at.changePLMN,
|
||||
"=> Changing MCC/MNC for: %s" % code, arg=code)
|
||||
statesmv(at.changeNetworkType,
|
||||
"=> Changing network type for 3G only", arg=14)
|
||||
statesmv(at.changeNetworkType,
|
||||
"=> Changing network type for 2G only", arg=13)
|
||||
statesmv(at.changeNetworkType,
|
||||
"=> Switching back to auto-mode", arg=2)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
state = False
|
||||
cells = kb.data['SM_cells']
|
||||
saveCells(cells)
|
||||
|
||||
def processOperatorADB(operators):
|
||||
sm = ADBshell()
|
||||
sm.androidsdkpath = mKB.config['androidsdk']
|
||||
state = True
|
||||
while state:
|
||||
try:
|
||||
for code in operators:
|
||||
statesmv(sm.deregister,
|
||||
"[+] Unregistered from current PLMN")
|
||||
statesmv(sm.changePLMN,
|
||||
"=> Changing MCC/MNC for: %s" % code, arg=code)
|
||||
statesmv(sm.changeNetworkType,
|
||||
"=> Changing network type for 3G only", arg=14)
|
||||
statesmv(sm.changeNetworkType,
|
||||
"=> Changing network type for 2G only", arg=13)
|
||||
statesmv(sm.changeNetworkType,
|
||||
"=> Switching back to auto-mode", arg=2)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
state = False
|
||||
kb = mKB()
|
||||
cells = kb.data['SM_cells']
|
||||
saveCells(cells)
|
||||
process = sm.grablogcat()
|
||||
|
||||
def processManualMCCMN(string):
|
||||
dic_ = {}
|
||||
splitted = string.replace(' ','').split(',')
|
||||
for code in splitted:
|
||||
dic_[code] = code
|
||||
return dic_
|
||||
|
||||
def load_operators():
|
||||
try:
|
||||
f = open('cache/operators.json', 'r')
|
||||
operators = json.loads(f.read())
|
||||
return operators
|
||||
if len(operators) > 0 or operators is not None:
|
||||
print (bcolors.WARNING+"Found %i operators in cache, do you want to reuse them?:\n\t%s"+bcolors.ENDC % (len(operators), str(operators)))
|
||||
answ = input('(Y)es or (N)o?')
|
||||
if answ.lower() is 'y':
|
||||
return operators
|
||||
f.close()
|
||||
except:
|
||||
return None
|
||||
|
||||
def saveMCCMNC(obj):
|
||||
jscache = json.dumps(obj, indent=4, sort_keys=True)
|
||||
f = open('cache/operators.json', 'w+')
|
||||
f.write(jscache)
|
||||
f.close()
|
Loading…
Reference in New Issue