"""
深度APK分析脚本 - 使用androguard库分析APK
"""
import os
import sys
import json
from pathlib import Path
try:
from androguard.core.bytecodes import apk, dvm
from androguard.core.analysis import analysis
ANDROGUARD_AVAILABLE = True
except ImportError:
ANDROGUARD_AVAILABLE = False
print("警告: androguard库未安装,将使用基础分析方法")
print("安装方法: pip install androguard")
APK_PATH = r"C:\Users\CYT\Desktop\base.apk"
OUTPUT_DIR = r"C:\Users\CYT\DevEcoStudioProjects\GlanceBrowser\apk_analysis"
def analyze_with_androguard():
"""使用androguard库分析APK"""
if not ANDROGUARD_AVAILABLE:
return None
print("使用androguard库分析APK...")
try:
a = apk.APK(APK_PATH)
apk_info = {
'package_name': a.get_package(),
'app_name': a.get_app_name(),
'version_name': a.get_androidversion_name(),
'version_code': a.get_androidversion_code(),
'min_sdk': a.get_min_sdk_version(),
'target_sdk': a.get_target_sdk_version(),
'permissions': a.get_permissions(),
'activities': a.get_activities(),
'services': a.get_services(),
'receivers': a.get_receivers(),
'providers': a.get_providers(),
}
d = dvm.DalvikVMFormat(a.get_dex())
dx = analysis.Analysis(d)
classes_info = []
for cls in d.get_classes():
class_name = cls.get_name()
if any(keyword in class_name.lower() for keyword in
['activity', 'fragment', 'adapter', 'view', 'browser', 'web',
'bookmark', 'history', 'download', 'setting', 'menu', 'tab',
'theme', 'night', 'reader', 'adblock', 'search']):
methods = []
for method in cls.get_methods():
method_name = method.get_name()
if not method_name.startswith('<'):
methods.append(method_name)
classes_info.append({
'name': class_name,
'methods': methods[:20],
'method_count': len(methods)
})
classes_info = sorted(classes_info, key=lambda x: x['method_count'], reverse=True)[:50]
return {
'apk_info': apk_info,
'classes': classes_info
}
except Exception as e:
print(f"androguard分析失败: {e}")
return None
def analyze_with_basic_tools():
"""基础分析方法(不依赖androguard)"""
import zipfile
import re
print("使用基础工具分析APK...")
apk_info = {
'package_name': '',
'permissions': [],
'activities': [],
'services': [],
'key_features': []
}
with zipfile.ZipFile(APK_PATH, 'r') as zip_ref:
try:
manifest_data = zip_ref.read('AndroidManifest.xml')
manifest_str = manifest_data.decode('latin-1', errors='ignore')
package_match = re.search(r'package="([^"]+)"', manifest_str)
if package_match:
apk_info['package_name'] = package_match.group(1)
permissions = re.findall(r'android\.permission\.([A-Z_]+)', manifest_str)
apk_info['permissions'] = list(set(permissions))
activities = re.findall(r'android:name="([^"]+Activity)"', manifest_str)
apk_info['activities'] = list(set(activities))[:20]
except Exception as e:
print(f"读取Manifest失败: {e}")
try:
dex_data = zip_ref.read('classes.dex')
dex_str = dex_data.decode('latin-1', errors='ignore')
features = []
if 'WebView' in dex_str:
features.append('WebView浏览器核心')
if 'WebChromeClient' in dex_str:
features.append('WebChromeClient(进度、标题)')
if 'WebViewClient' in dex_str:
features.append('WebViewClient(页面事件)')
if 'Bookmark' in dex_str or 'bookmark' in dex_str:
features.append('书签管理')
if 'History' in dex_str or 'history' in dex_str:
features.append('历史记录')
if 'Download' in dex_str or 'download' in dex_str:
features.append('下载管理')
if 'TabManager' in dex_str or 'TabLayout' in dex_str:
features.append('多标签页管理')
if 'SearchView' in dex_str or 'EditText' in dex_str:
features.append('搜索功能')
if 'Menu' in dex_str or 'PopupMenu' in dex_str:
features.append('菜单系统')
if 'AdBlock' in dex_str or 'AdBlocker' in dex_str:
features.append('广告拦截')
if 'NightMode' in dex_str or 'night' in dex_str:
features.append('夜间模式')
if 'ReaderMode' in dex_str or 'reader' in dex_str:
features.append('阅读模式')
if 'Theme' in dex_str or 'theme' in dex_str:
features.append('主题管理')
if 'FindInPage' in dex_str or 'find' in dex_str:
features.append('页面查找')
if 'UserAgent' in dex_str or 'UA' in dex_str:
features.append('用户代理切换')
if 'SharedPreferences' in dex_str:
features.append('设置持久化')
if 'Database' in dex_str or 'SQLite' in dex_str:
features.append('数据库存储')
if 'JavaScript' in dex_str or 'JS' in dex_str:
features.append('JavaScript支持')
if 'Cookie' in dex_str:
features.append('Cookie管理')
if 'Cache' in dex_str:
features.append('缓存管理')
if 'Proxy' in dex_str:
features.append('代理设置')
if 'Certificate' in dex_str or 'SSL' in dex_str:
features.append('SSL证书管理')
apk_info['key_features'] = list(set(features))
except Exception as e:
print(f"分析DEX失败: {e}")
return apk_info
def analyze_layouts_detailed():
"""详细分析布局文件"""
import zipfile
import re
print("分析布局文件...")
layouts = {}
with zipfile.ZipFile(APK_PATH, 'r') as zip_ref:
for file in zip_ref.namelist():
if 'layout' in file and file.endswith('.xml'):
try:
layout_data = zip_ref.read(file)
layout_str = layout_data.decode('latin-1', errors='ignore')
layout_name = os.path.basename(file).replace('.xml', '')
components = []
ui_components = {
'EditText': '输入框',
'Button': '按钮',
'ImageView': '图片视图',
'TextView': '文本视图',
'RecyclerView': '列表视图',
'ListView': '列表视图',
'WebView': '网页视图',
'Toolbar': '工具栏',
'BottomNavigationView': '底部导航',
'DrawerLayout': '抽屉布局',
'CoordinatorLayout': '协调布局',
'AppBarLayout': '应用栏布局',
'SwipeRefreshLayout': '下拉刷新',
'ProgressBar': '进度条',
'SearchView': '搜索视图',
'FloatingActionButton': '浮动按钮',
'CardView': '卡片视图',
'TabLayout': '标签布局',
'ViewPager': '翻页视图',
'LinearLayout': '线性布局',
'RelativeLayout': '相对布局',
'FrameLayout': '帧布局',
'ConstraintLayout': '约束布局',
'GridLayout': '网格布局',
'Spinner': '下拉选择',
'CheckBox': '复选框',
'RadioButton': '单选按钮',
'Switch': '开关',
'SeekBar': '滑动条',
'RatingBar': '评分条',
'ScrollView': '滚动视图',
'NestedScrollView': '嵌套滚动视图',
'HorizontalScrollView': '横向滚动视图',
'ViewFlipper': '视图切换器',
'TextSwitcher': '文本切换器',
'ImageSwitcher': '图片切换器',
'ViewSwitcher': '视图切换器',
'DatePicker': '日期选择器',
'TimePicker': '时间选择器',
'NumberPicker': '数字选择器',
'CalendarView': '日历视图',
'Chronometer': '计时器',
'AnalogClock': '模拟时钟',
'DigitalClock': '数字时钟',
'SurfaceView': '表面视图',
'TextureView': '纹理视图',
'VideoView': '视频视图',
'MapView': '地图视图',
'AdView': '广告视图',
'ProgressBar': '进度条',
'ProgressDialog': '进度对话框',
'AlertDialog': '警告对话框',
'DatePickerDialog': '日期选择对话框',
'TimePickerDialog': '时间选择对话框',
}
for component, name in ui_components.items():
if component in layout_str:
components.append(name)
if components:
layouts[layout_name] = {
'components': list(set(components)),
'file_path': file
}
except Exception as e:
pass
return layouts
def compare_with_glance_browser(apk_info, layouts):
"""对比观澜浏览器"""
print("\n" + "="*80)
print("Via浏览器 vs 观澜浏览器 功能对比分析")
print("="*80)
glance_features = {
'WebView浏览器核心': True,
'WebChromeClient(进度、标题)': True,
'WebViewClient(页面事件)': True,
'书签管理': True,
'历史记录': True,
'下载管理': True,
'多标签页管理': True,
'搜索功能': True,
'菜单系统': True,
'广告拦截': True,
'夜间模式': True,
'阅读模式': False,
'主题管理': True,
'页面查找': True,
'用户代理切换': False,
'设置持久化': True,
'数据库存储': True,
'JavaScript支持': True,
'Cookie管理': True,
'缓存管理': True,
'代理设置': False,
'SSL证书管理': False,
}
print("\n【功能对比】")
print(f"{'功能':<30} {'Via浏览器':<15} {'观澜浏览器':<15} {'状态':<10}")
print("-"*80)
via_features = apk_info.get('key_features', [])
for feature, glance_has in glance_features.items():
via_has = feature in via_features
status = '✅ 一致' if via_has == glance_has else '⚠️ 差异'
print(f"{feature:<30} {'✅' if via_has else '❌':<15} {'✅' if glance_has else '❌':<15} {status:<10}")
via_only = [f for f in via_features if f not in glance_features]
if via_only:
print("\n【Via独有功能】")
for feature in via_only:
print(f"- {feature}")
glance_only = [f for f, has in glance_features.items() if has and f not in via_features]
if glance_only:
print("\n【观澜独有功能】")
for feature in glance_only:
print(f"- {feature}")
print("\n【布局组件对比】")
print(f"Via浏览器布局文件数: {len(layouts)}")
component_count = {}
for layout_info in layouts.values():
for comp in layout_info['components']:
component_count[comp] = component_count.get(comp, 0) + 1
print("\nVia浏览器UI组件使用频率:")
for comp, count in sorted(component_count.items(), key=lambda x: x[1], reverse=True)[:15]:
print(f"- {comp}: {count}次")
return {
'via_features': via_features,
'glance_features': glance_features,
'via_only': via_only,
'glance_only': glance_only,
'layouts': layouts,
'component_count': component_count
}
def generate_detailed_report(comparison_result, apk_info):
"""生成详细报告"""
report_path = os.path.join(OUTPUT_DIR, 'analysis', 'detailed_comparison.json')
report = {
'via_apk_info': apk_info,
'comparison': comparison_result,
'summary': {
'via_feature_count': len(comparison_result['via_features']),
'glance_feature_count': sum(1 for v in comparison_result['glance_features'].values() if v),
'via_only_count': len(comparison_result['via_only']),
'glance_only_count': len(comparison_result['glance_only']),
'layout_count': len(comparison_result['layouts']),
}
}
with open(report_path, 'w', encoding='utf-8') as f:
json.dump(report, f, indent=2, ensure_ascii=False)
print(f"\n详细对比报告已保存: {report_path}")
def main():
"""主函数"""
print("开始深度分析Via浏览器APK...")
if not os.path.exists(APK_PATH):
print(f"错误: APK文件不存在: {APK_PATH}")
return
os.makedirs(os.path.join(OUTPUT_DIR, 'analysis'), exist_ok=True)
if ANDROGUARD_AVAILABLE:
apk_analysis = analyze_with_androguard()
if apk_analysis:
apk_info = apk_analysis['apk_info']
apk_info['key_features'] = [cls['name'] for cls in apk_analysis['classes'][:20]]
else:
apk_info = analyze_with_basic_tools()
else:
apk_info = analyze_with_basic_tools()
layouts = analyze_layouts_detailed()
comparison_result = compare_with_glance_browser(apk_info, layouts)
generate_detailed_report(comparison_result, apk_info)
print("\n分析完成!")
if __name__ == '__main__':
main()