mirror of
https://github.com/androguard/androguard.git
synced 2024-11-27 15:01:03 +00:00
Added tool to extract permission mappings from PScout data
This commit is contained in:
parent
48c3f7d218
commit
ae52ec426e
254
tools/permissions/extract_api_permission_mappings.py
Normal file
254
tools/permissions/extract_api_permission_mappings.py
Normal file
@ -0,0 +1,254 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# This file is part of Androguard.
|
||||
#
|
||||
# This is a tool to extract permissions and permission groups from Android Open Source Project.
|
||||
# The information about the permissions and permission groups is appended to a file, which is
|
||||
# later used in Androguard project.
|
||||
#
|
||||
# Author: Yury Zhauniarovich
|
||||
#
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
#CONSTANTS
|
||||
PATH_TO_PSCOUT_FOLDER = "/home/yury/TMP/PScout/results/API_09"
|
||||
API_VERSION = 9
|
||||
|
||||
|
||||
MAPPINGS_MODULE_PATH = "../../androguard/core/api_specific_resources/api_permission_mappings/" #where to append the results
|
||||
MAPPINGS_MODULE_NAME = "api_permission_mappings"
|
||||
|
||||
PSCOUT_METHOD_MAPPING_FILENAME = "allmappings"
|
||||
PSCOUT_CONTENTPROVIDERFIELDS_MAPPING_FILENAME = "contentproviderfieldpermission"
|
||||
|
||||
METHODS_MAPPING_PARAM_NAME = "AOSP_PERMISSIONS_BY_METHODS"
|
||||
FIELDS_MAPPING_PARAM_NAME = "AOSP_PERMISSIONS_BY_FIELDS"
|
||||
|
||||
|
||||
#IMPORTS
|
||||
import os, re, codecs
|
||||
|
||||
|
||||
#auxiliary
|
||||
TYPE_DESCRIPTOR = {
|
||||
'V': 'void',
|
||||
'Z': 'boolean',
|
||||
'B': 'byte',
|
||||
'S': 'short',
|
||||
'C': 'char',
|
||||
'I': 'int',
|
||||
'J': 'long',
|
||||
'F': 'float',
|
||||
'D': 'double',
|
||||
}
|
||||
|
||||
DESCRIPTOR_TYPE = {
|
||||
'void' : 'V',
|
||||
'boolean' : 'Z',
|
||||
'byte' : 'B',
|
||||
'short' : 'S',
|
||||
'char' : 'C',
|
||||
'int' : 'I',
|
||||
'long' : 'J',
|
||||
'float' : 'F',
|
||||
'double' : 'D',
|
||||
}
|
||||
|
||||
def countBrackets(atype):
|
||||
res = re.findall('\[\s*\]', atype)
|
||||
return len(res)
|
||||
|
||||
def transformClassParam(atype):
|
||||
res = ""
|
||||
arrDim = countBrackets(atype)
|
||||
if arrDim > 0:
|
||||
pos = atype.find('[')
|
||||
atype = atype[0 : pos].strip()
|
||||
res = '['*arrDim
|
||||
|
||||
if atype in DESCRIPTOR_TYPE:
|
||||
res += DESCRIPTOR_TYPE[atype]
|
||||
else:
|
||||
res += FormatClassToJava(atype)
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def FormatClassToJava(input) :
|
||||
"""
|
||||
Transoform a typical xml format class into java format
|
||||
|
||||
:param input: the input class name
|
||||
:rtype: string
|
||||
"""
|
||||
return "L" + input.replace(".", "/") + ";"
|
||||
|
||||
|
||||
def parseMethod(methodString):
|
||||
ms = methodString.strip()
|
||||
|
||||
mParamStartPos = ms.find('(')
|
||||
mParamEndPos = ms.find(')')
|
||||
paramString = ms[mParamStartPos + 1 : mParamEndPos].strip()
|
||||
params = [l.strip() for l in paramString.split(',')]
|
||||
|
||||
retValue_mName = ms[0 : mParamStartPos].strip()
|
||||
mNameStartPos = retValue_mName.rfind(' ')
|
||||
returnValue = retValue_mName[0 : mNameStartPos].strip()
|
||||
methodName = retValue_mName[mNameStartPos + 1 : ].strip()
|
||||
|
||||
return (methodName, params, returnValue)
|
||||
#end of auxiliary
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print "Starting conversion of PScout data: [%s]" % PATH_TO_PSCOUT_FOLDER
|
||||
|
||||
if not os.path.exists(MAPPINGS_MODULE_PATH):
|
||||
os.makedirs(MAPPINGS_MODULE_PATH)
|
||||
|
||||
print "Checking if we already have the file with the version %d..." % API_VERSION
|
||||
api_specific_mappings_module_name = "%s_api%s.py" % (MAPPINGS_MODULE_NAME, API_VERSION)
|
||||
api_specific_mappings_module_path = os.path.join(MAPPINGS_MODULE_PATH, api_specific_mappings_module_name)
|
||||
if os.path.exists(api_specific_mappings_module_path):
|
||||
print "API specific file for this version already exists!"
|
||||
print "If you want create a file for newer version, please, delete file: %s" % api_specific_mappings_module_path
|
||||
exit(1)
|
||||
|
||||
|
||||
|
||||
|
||||
print "Reading method mapping file..."
|
||||
pscout_method_mapping_filepath = os.path.join(PATH_TO_PSCOUT_FOLDER, PSCOUT_METHOD_MAPPING_FILENAME)
|
||||
methods_mapping_file_lines = []
|
||||
with open(pscout_method_mapping_filepath, 'r') as pscout_file:
|
||||
methods_mapping_file_lines = pscout_file.readlines()
|
||||
|
||||
|
||||
print "Starting to parse file: [%s]" % pscout_method_mapping_filepath
|
||||
perm_name = None
|
||||
methods_mapping = {}
|
||||
for line in methods_mapping_file_lines:
|
||||
line = line.strip()
|
||||
if line.startswith("Permission:"):
|
||||
perm_name = line.split("Permission:")[1].strip()
|
||||
print "PROCESSING PERMISSIONS: %s" % perm_name
|
||||
elif line.startswith("<"):
|
||||
class_method = line[line.find('<') + 1 : line.rfind('>')]
|
||||
sepPos = class_method.find(':')
|
||||
className = class_method[0 : sepPos].strip()
|
||||
|
||||
methodStr = class_method[sepPos + 1 :].strip()
|
||||
methodName, params, returnValue = parseMethod(methodStr)
|
||||
|
||||
modParStr = ""
|
||||
for par in params:
|
||||
if par != "":
|
||||
modParStr += transformClassParam(par) + ' '
|
||||
modParStr = modParStr.strip()
|
||||
|
||||
method_identificator = "%s-%s-(%s)%s" % (transformClassParam(className), methodName, modParStr, transformClassParam(returnValue))
|
||||
|
||||
try:
|
||||
methods_mapping[method_identificator].add(perm_name)
|
||||
except KeyError:
|
||||
methods_mapping[method_identificator] = set()
|
||||
methods_mapping[method_identificator].add(perm_name)
|
||||
|
||||
|
||||
|
||||
print "Reading contentproviderfield mapping file..."
|
||||
pscout_contentproviderfields_mapping_filepath = os.path.join(PATH_TO_PSCOUT_FOLDER, PSCOUT_CONTENTPROVIDERFIELDS_MAPPING_FILENAME)
|
||||
contentproviderfields_mapping_file_lines = []
|
||||
with open(pscout_contentproviderfields_mapping_filepath, 'r') as pscout_file:
|
||||
contentproviderfields_mapping_file_lines = pscout_file.readlines()
|
||||
|
||||
perm_name = None
|
||||
fields_mapping = {}
|
||||
for line in contentproviderfields_mapping_file_lines:
|
||||
line = line.strip()
|
||||
if line.startswith("PERMISSION:"):
|
||||
perm_name = line.split("PERMISSION:")[1].strip()
|
||||
print "PROCESSING PERMISSIONS: %s" % perm_name
|
||||
elif line.startswith("<"):
|
||||
field_entry = line[line.find('<') + 1 : line.rfind('>')]
|
||||
classNameSepPos = field_entry.find(':')
|
||||
className = field_entry[0 : classNameSepPos].strip()
|
||||
|
||||
proto_name_str = field_entry[classNameSepPos + 1 :].strip()
|
||||
proto_name_parts = proto_name_str.split()
|
||||
proto = proto_name_parts[0].strip()
|
||||
name = proto_name_parts[1].strip()
|
||||
|
||||
field_identificator = "%s-%s-%s" % (transformClassParam(className), name, transformClassParam(proto))
|
||||
|
||||
try:
|
||||
fields_mapping[field_identificator].add(perm_name)
|
||||
except KeyError:
|
||||
fields_mapping[field_identificator] = set()
|
||||
fields_mapping[field_identificator].add(perm_name)
|
||||
|
||||
|
||||
|
||||
print "Appending found information to the mappings file..."
|
||||
with codecs.open(api_specific_mappings_module_path, 'w', 'utf-8') as perm_py_module:
|
||||
perm_py_module.write('#!/usr/bin/python\n')
|
||||
perm_py_module.write('# -*- coding: %s -*-\n\n' % 'utf-8')
|
||||
|
||||
perm_py_module.write('# This file is a part of Androguard.\n')
|
||||
perm_py_module.write('#\n')
|
||||
perm_py_module.write('# This file is generated automatically from the data\n')
|
||||
perm_py_module.write('# provided by PScout tool [http://pscout.csl.toronto.edu/]\n')
|
||||
perm_py_module.write('# using script: %s\n' % os.path.basename(__file__))
|
||||
perm_py_module.write('#\n')
|
||||
perm_py_module.write('# Author: Yury Zhauniarovich\n')
|
||||
perm_py_module.write('#\n')
|
||||
perm_py_module.write('#\n')
|
||||
perm_py_module.write('# Licensed under the Apache License, Version 2.0 (the "License");\n')
|
||||
perm_py_module.write('# you may not use this file except in compliance with the License.\n')
|
||||
perm_py_module.write('# You may obtain a copy of the License at\n')
|
||||
perm_py_module.write('#\n')
|
||||
perm_py_module.write('# http://www.apache.org/licenses/LICENSE-2.0\n')
|
||||
perm_py_module.write('#\n')
|
||||
perm_py_module.write('# Unless required by applicable law or agreed to in writing, software\n')
|
||||
perm_py_module.write('# distributed under the License is distributed on an "AS-IS" BASIS,\n')
|
||||
perm_py_module.write('# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n')
|
||||
perm_py_module.write('# See the License for the specific language governing permissions and\n')
|
||||
perm_py_module.write('# limitations under the License"\n\n')
|
||||
|
||||
perm_py_module.write('#################################################\n')
|
||||
perm_py_module.write('### API version: %d \n' % API_VERSION)
|
||||
perm_py_module.write('#################################################\n\n\n')
|
||||
|
||||
perm_py_module.write("%s = {\n" % METHODS_MAPPING_PARAM_NAME)
|
||||
for method in methods_mapping.keys():
|
||||
permissions = methods_mapping.get(method)
|
||||
perms_string = ", ".join(['"%s"' % prm for prm in permissions])
|
||||
perm_py_module.write("\t'%s' : [%s],\n" % (method, perms_string))
|
||||
perm_py_module.write("}\n\n")
|
||||
|
||||
perm_py_module.write("%s = {\n" % FIELDS_MAPPING_PARAM_NAME)
|
||||
for field in fields_mapping.keys():
|
||||
permissions = fields_mapping.get(field)
|
||||
perms_string = ", ".join(['"%s"' % prm for prm in permissions])
|
||||
perm_py_module.write("\t'%s' : [%s],\n" % (field, perms_string))
|
||||
perm_py_module.write("}\n")
|
||||
perm_py_module.write("#################################################\n")
|
||||
|
||||
|
||||
|
||||
print "Done..."
|
Loading…
Reference in New Issue
Block a user