python提取android工程代码中的一些数据

文章讲述了如何使用Python脚本处理Java代码,提取特定关键字,如字符串和库对象引用。在遇到因代码格式化导致的换行问题时,通过拼接行内容解决了匹配遗漏的问题。同时,作者希望找到更高效的Python库来解析Java文件,生成可直接使用的数据结构。
摘要由CSDN通过智能技术生成

事情是这样的,由于一些原因我需要把Java代码中的一些关键词筛选出来,并将其行号,命中内容等都筛选出来。以此为数据源做后续的扫描识别工作。

分析目标关键词类型,可以分为两类:字符串和库对象引用。

  • 字符串样例:"android.permission.READ_CALENDAR"
  • 库对象引用样例Manifest.permission.CAMERA

所以首先就是把工程中的java文件都读入到内存中,然后按行遍历内容,逐个匹配关键字,当匹配上后,就记录文件、行号以及命中内容。很好,很简单。于是有了下面的代码。

import re
import os

PERMISSION_PATTERN = [r'android.permission.[a-zA-Z]*', r'Manifest.permission.[a-zA-Z]*']

# 获取某目录下所有的java文件路径
def read_all_java(file_dir):
    # 读取目录下所有Java的内容

    
def find_all_permission_statement_place(line):
    for p in PERMISSION_PATTERN:
        find = re.findall(p, line)
        if find:
            return find[0]
    return None

看起来很不错,我甚至用了个常量组,方便日后的扩展。我真是个小天才。

但是当脚本跑起来后,有几个已知的代码段落没有被识别出来。对于一个想要用脚本偷懒的人来说,漏场景实在是太可怕了,于是赶紧分析被遗漏的场景。经分析,这些被遗漏的场景是由于Java代码格式化时,由于某行代码过长而换行导致的。如下例。

    String pe = Manifest.permission
				.CAMERA;

这种这行实在是太讨厌了,举一反三,除了这种对象链换行,还有一种字符串换行。所以,如果想用上面的代码段将所有场景都扫描出来,我们需要将折行的代码重新拼接起来。

	public static final String WRITE_EXTERNAL_STORAGE = "android.permission" +
            ".WRITE_EXTERNAL_STORAGE"

经分析,可以将目前两种目标关键字的折行类型分为四种,分别为,“.”行首、“.”行尾、“+”行首、“+”行尾。

    // “.”行首
    String pe = Manifest.permission
				.CAMERA;
    // “.”行尾
    String pe = Manifest.permission.
				CAMERA;
    // "+"行首 
	public static final String WRITE_EXTERNAL_STORAGE = "android.permission"
            + ".WRITE_EXTERNAL_STORAGE"
    // "+"行尾
	public static final String WRITE_EXTERNAL_STORAGE = "android.permission" +
            ".WRITE_EXTERNAL_STORAGE"

对于上述四种场景,我们需要对原始数据进行一次清洗。具体实现如下。

def read_file_and_format(file_dir):
    """
    读取文件内容,以列表形式返回

    会将其因为格式化而造成的".","+"换行恢复
    """
    origin_data = read_file(file_dir)
    result = []
    index = 0
    point_cache = None
    plus_sign_cache = None
    for d in origin_data:
        # 行首"."换行处理
        if d.strip().startswith("."):
            pre_line = result[index - 1]
            result[index - 1] = (pre_line + d.strip())
            continue
        # 行尾"."换行处理
        if point_cache:
            d = point_cache + d.strip()
            point_cache = None
        if d.strip().endswith("."):
            point_cache = d.replace("\n", "")
            continue

        # 行首字符串"+"换行处理
        if d.strip().startswith("+"):
            find = re.findall(r'[\+][\s*]["]', d.strip())
            if find:
                pre_line = result[index - 1].strip()[:-1]
                result[index - 1] = pre_line + d.strip().replace(find[0], "")
                continue
        # 行尾字符串"+"换行处理
        if plus_sign_cache:
            d = plus_sign_cache + d.strip()[1:len(d)]
            plus_sign_cache = None
        if d.strip().endswith("+"):
            find = re.findall(r'["][\s*][\+]', d.strip())
            if find:
                plus_sign_cache = d.strip().replace(find[0], "").replace("\n", "")
                continue

        index = index + 1
        result.append(d.replace("\n", ""))
    return result

上述处理很土鳖,就是遍历整体文件,然后按照特征找出对应的行,上下拼接。好歹把功能实现了,其中使用的正则都是我一点一点试出来的,挺费劲,记录一下,以资来者。

这个过程中有个坑,就是习惯了Java的replace支持正则替换,但python的replace不支持,在这里无效定位了半天。

另外,其实聪明如你的小伙伴已经看出来了,我其实想要使用python脚本来把Android权限相关内容提取出来,这块不清楚有没有比较牛的python库可以直接解析Java文件,然后返回python中可以直接调用的类、方法、成员变量等等的数据结构。望大神们清楚地点拨一二,小子不胜感激。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kiba_zwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值