Preface
I believe that the students who have recently put on the App in the App Store have felt that the domestic attaches more and more attention to user privacy, such as MAC address, device ID, IMEI information, etc., either simply don’t use it, or you must clearly tell users that they want to get For this information, related laws and regulations, please refer to the "Cyber Security Law" and "Notice on Carrying out Special Rectification Work for APP Infringement of User Rights and Interests"
Straight to the point
Not much nonsense, I found a few decompilation tools, and briefly looked at the usage method, and finally locked androguard, the official explanation: reverse engineering, malware and malware analysis of Android applications, it provides a series of Apk As well as the analysis and processing functions of dex, odex, arsc and other files, it can easily help us find the place to call system permissions. And the execution of the python script is simply not usable anymore
surroundings
python
https://www.python.org
pycharm
https://www.jetbrains.com/pycharm/download/
androguard
https://androguard.readthedocs.io/en/latest/
installation
pip install -U androguard
If you want to operate directly on the command line, please perform the following after installation:
androguard analyze
As shown in the figure after execution:
Then load the apk. After executing the above, enter the following:a, d, dx = AnalyzeAPK("examples/android/abcore/app-prod-debug.apk")
After the apk is loaded, you can call the relevant api to get the information
Get permission
In [2]: a.get_permissions() Out[2]: ['android.permission.INTERNET', 'android.permission.WRITE_EXTERNAL_STORAGE', 'android.permission.ACCESS_WIFI_STATE', 'android.permission.ACCESS_NETWORK_STATE']
Get Activity
In [3]: a.get_activities() Out[3]: ['com.greenaddress.abcore.MainActivity', 'com.greenaddress.abcore.BitcoinConfEditActivity', 'com.greenaddress.abcore.AboutActivity', 'com.greenaddress.abcore.SettingsActivity', 'com.greenaddress.abcore.DownloadSettingsActivity', 'com.greenaddress.abcore.PeerActivity', 'com.greenaddress.abcore.ProgressActivity', 'com.greenaddress.abcore.LogActivity', 'com.greenaddress.abcore.ConsoleActivity', 'com.greenaddress.abcore.DownloadActivity']
other
# 包名 In [4]: a.get_package() Out[4]: 'com.greenaddress.abcore' # app名字 In [5]: a.get_app_name() Out[5]: u'ABCore' # logo In [6]: a.get_app_icon() Out[6]: u'res/mipmap-xxxhdpi-v4/ic_launcher.png' # 版本号 In [7]: a.get_androidversion_code() Out[7]: '2162' # 版本名 In [8]: a.get_androidversion_name() Out[8]: '0.62' # 最低sdk支持 In [9]: a.get_min_sdk_version() Out[9]: '21' # 最高 In [10]: a.get_max_sdk_version() # 目标版本 In [11]: a.get_target_sdk_version() Out[11]: '27' # 获取有效目标版本 In [12]: a.get_effective_target_sdk_version() Out[12]: 27 # manifest文件 In [13]: a.get_android_manifest_xml() Out[13]: <Element manifest at 0x7f9d01587b00>
Wait a minute, there are too many Apis, let's pay attention to the official documents, only you can't think of it, without it, the following link:
https://androguard.readthedocs.io/en/latest/intro/gettingstarted.html#using-the-analysis-object
More demo
https://github.com/androguard/androguard/tree/master/examples
Let's start the practice directly.
Retrieve places where sensitive permissions are used and output files
The following is the implementation of checking the use of sensitive permissions in the APK, please see:
import os
import sys
# 引入androguard的路径,根据个人存放的位置而定
androguard_module_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'androguard')
if not androguard_module_path in sys.path:
sys.path.append(androguard_module_path)
from androguard.misc import AnalyzeAPK
from androguard.core.androconf import load_api_specific_resource_module
path = r"/apk"
out_path = r"/out"
files = []
path_list = os.listdir(path)
path_list.sort()
for name in path_list:
if os.path.isfile(os.path.join(path, name)):
files.append(name)
def main():
for apkFile in files:
file_name = os.path.splitext(apkFile)[0]
print(apkFile)
out = AnalyzeAPK(path + '/' + apkFile)
# apk object 抽象apk对象,可以获取apk的一些信息,如版本号、包名、Activity等
a = out[0]
# DalvikVMFormat 数组,一个元素其实对应的是class.dex,可以从DEX文件中获取类、方法或字符串。
d = out[1]
# Analysis 分析对象,因为它包含特殊的类,这些类链接有关classes.dex的信息,甚至可以一次处理许多dex文件,所以下面我们从这里面来分析整个apk
dx = out[2]
# api和权限映射
# 输出文件路径
api_perm_filename = os.path.join(out_path, file_name + "_api-perm.txt")
api_perm_file = open(api_perm_filename, 'w', encoding='utf-8')
# 权限映射map
permissionMap = load_api_specific_resource_module('api_permission_mappings')
# 遍历apk所有方法
for meth_analysis in dx.get_methods():
meth = meth_analysis.get_method()
# 获取类名、方法名
name = meth.get_class_name() + "-" + meth.get_name() + "-" + str(
meth.get_descriptor())
for k, v in permissionMap.items():
# 匹配系统权限方法,匹配上就输出到文件中
if name == k:
result = str(meth) + ' : ' + str(v)
api_perm_file.write(result + '\n')
api_perm_file.close()
if __name__ == '__main__':
main()
Output result
Landroid/app/Activity;->navigateUpTo(Landroid/content/Intent;)Z : ['android.permission.BROADCAST_STICKY']
Landroid/app/Activity;->onMenuItemSelected(I Landroid/view/MenuItem;)Z : ['android.permission.BROADCAST_STICKY']
Landroid/app/Activity;->setRequestedOrientation(I)V : ['android.permission.BROADCAST_STICKY']
Landroid/app/Activity;->unregisterReceiver(Landroid/content/BroadcastReceiver;)V : ['android.permission.BROADCAST_STICKY']
Landroid/os/PowerManager$WakeLock;->acquire(J)V : ['android.permission.WAKE_LOCK']
Landroid/os/PowerManager$WakeLock;->release()V : ['android.permission.WAKE_LOCK']
Landroid/location/LocationManager;->isProviderEnabled(Ljava/lang/String;)Z : ['android.permission.ACCESS_COARSE_LOCATION', 'android.permission.ACCESS_FINE_LOCATION']
Landroid/location/LocationManager;->getLastKnownLocation(Ljava/lang/String;)Landroid/location/Location; : ['android.permission.ACCESS_COARSE_LOCATION', 'android.permission.ACCESS_FINE_LOCATION']
Landroid/app/ActivityManager;->getRunningTasks(I)Ljava/util/List; : ['android.permission.GET_TASKS']
Landroid/accounts/AccountManager;->invalidateAuthToken(Ljava/lang/String; Ljava/lang/String;)V : ['android.permission.MANAGE_ACCOUNTS', 'android.permission.USE_CREDENTIALS']
Landroid/net/ConnectivityManager;->getNetworkInfo(I)Landroid/net/NetworkInfo; : ['android.permission.ACCESS_NETWORK_STATE']
Landroid/net/ConnectivityManager;->isActiveNetworkMetered()Z : ['android.permission.ACCESS_NETWORK_STATE']
Landroid/net/ConnectivityManager;->getActiveNetworkInfo()Landroid/net/NetworkInfo; : ['android.permission.ACCESS_NETWORK_STATE']
Landroid/telephony/TelephonyManager;->getDeviceId()Ljava/lang/String; : ['android.permission.READ_PHONE_STATE']
Landroid/telephony/TelephonyManager;->getSubscriberId()Ljava/lang/String; : ['android.permission.READ_PHONE_STATE']
Landroid/telephony/TelephonyManager;->getSimSerialNumber()Ljava/lang/String; : ['android.permission.READ_PHONE_STATE']
The output system class, calling method, and required permissions.
Retrieve where a system method is called and print
import os
import sys
# 引入androguard的路径,根据个人存放的位置而定
androguard_module_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'androguard')
if not androguard_module_path in sys.path:
sys.path.append(androguard_module_path)
from androguard.misc import AnalyzeAPK
from androguard.core.androconf import load_api_specific_resource_module
path = r"/apk"
out_path = r"/out"
files = []
path_list = os.listdir(path)
path_list.sort()
for name in path_list:
if os.path.isfile(os.path.join(path, name)):
files.append(name)
def main():
for apkFile in files:
file_name = os.path.splitext(apkFile)[0]
print(apkFile)
out = AnalyzeAPK(path + '/' + apkFile)
a = out[0]
d = out[1]
dx = out[2]
for meth in dx.classes['Ljava/io/File;'].get_methods():
print("usage of method {}".format(meth.name))
# 拿到改函数的引用函数
for _, call, _ in meth.get_xref_from():
print(" called by -> {} -- {}".format(call.class_name, call.name))
if __name__ == '__main__':
main()
Output result
usage of method getPath
called by -> Landroid/support/v4/util/AtomicFile; -- <init>
usage of method <init>
called by -> Landroid/support/v4/util/AtomicFile; -- <init>
usage of method delete
called by -> Landroid/support/v4/util/AtomicFile; -- failWrite
called by -> Landroid/support/v4/util/AtomicFile; -- delete
called by -> Landroid/support/v4/util/AtomicFile; -- delete
called by -> Landroid/support/v4/util/AtomicFile; -- startWrite
called by -> Landroid/support/v4/util/AtomicFile; -- openRead
called by -> Landroid/support/v4/util/AtomicFile; -- finishWrite
usage of method renameTo
called by -> Landroid/support/v4/util/AtomicFile; -- openRead
called by -> Landroid/support/v4/util/AtomicFile; -- failWrite
called by -> Landroid/support/v4/util/AtomicFile; -- startWrite
usage of method exists
called by -> Landroid/support/v4/util/AtomicFile; -- startWrite
called by -> Landroid/support/v4/util/AtomicFile; -- openRead
called by -> Landroid/support/v4/util/AtomicFile; -- startWrite
usage of method getParentFile
called by -> Landroid/support/v4/util/AtomicFile; -- startWrite
usage of method mkdir
called by -> Landroid/support/v4/util/AtomicFile; -- startWrite
- 'Ljava/io/File;' Need to detect the class
- meth.get_xref_from() where the function in this class is referenced
You can also make an array yourself, configure the related functions to be checked, and then add if filtering in the above code.
If you want to find the Android system to locate and which methods are called by the application, you can do this:dx.classes['Landroid/location/LocationManager;']
Run the script again to see the results.
the end
The main purpose of writing this blog is to let more people know about this. When I searched the article myself, I found that there was not much to refer to, which caused many people to be unable to start, but in fact, the official document is also very detailed, but it is in English. , It seems inconvenient, and I hope this short article will help you, if you have any questions, please contact me or leave a comment
Welcome to follow the new website
- http://jetpack.net.cn
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。