Android如何自动校验版本号,渠道号,签名和混淆

来源:互联网 发布:人工智能包括哪些方面 编辑:程序博客网 时间:2024/06/16 19:27

为什么

每次发给测试的apk,测试都需要校验AndroidManifest.xml中的版本号,渠道号,apk的签名和代码是否混淆。每次用人力去做太麻烦,我们希望用自动化脚本将这些数据展示到文本中,然后人力核对本文。这对一次打上百个包来说是唯一的可行方案。

做什么

  • 获取apk签名的md5和sha1
  • 收集AndroidManifest.xml中的版本号、版本名、渠道号
  • 获取apk中class文件中被混淆的class的个数
  • 将上述内容用表格显示出来

怎么做

实现环境

操作系统:linux
语言:python

1. 将apk中的指定文件解压

在校验过程中,我们只需要三个文件如下
- AndroidManifest.xml:获取版本名,版本号和渠道号
- META-INF/CERT.RSA:获取签名信息
- classes.dex:获取java类信息
这里不需要将manifest全部解压

fileArray=['AndroidManifest.xml','META-INF/CERT.RSA','classes.dex']zfile = zipfile.ZipFile(fname,'r')for filename in zfile.namelist():    if filename in fileArray:        data = zfile.read(filename)        if '/' in filename:            filename=filename.split('/')[1]        wfile = open(filename,'w+b')        wfile.write(data)        wfile.close()

2. 获取apk的签名信息

获取apk签名用java自带工具keytool。keytool会将CERT.RSA中的相应信息打印出来,如下所示。

Serial number: 12345678Valid from: Wed Sep 04 12:21:54 CST 2013 until: Tue Jan 05 12:21:54 CST 3013Certificate fingerprints:     MD5:  00:00:00:00:DC:FE:D1:F5:A0:FB:21:E1:12:34:56:78     SHA1: 00:00:00:00:1A:FF:7F:16:A8:3F:46:D0:06:EF:95:82:12:34:56:78     Signature algorithm name: SHA256withRSA     Version: 3

这里我们需要从输出的文本中提取触MD5和SHA1

signature = os.popen('keytool -printcert -file CERT.RSA').readlines()md5=''sha1=''for line in signature:    if 'MD5' in line:        md5=line[line.rindex(' ')+1:].replace('\n','')    elif 'SHA1' in line:        sha1=line[line.rindex(' ')+1:].replace('\n','')

3. 将AndroidManifest.xml由二进制转换成文本,并提取触相应信息

解压出来的AndroidManifest.xml是二进制文件,我们需要先用工具将其转换成文本,再提取信息。

以下是axml.sh的代码,用网上提供的axml.jar进行反编译

#!/bin/bashjava -jar /opt/android/reverse/axml.jar $1

反编译之后会出现如下信息:

<manifest    android:versionCode="<0x4F, type 0x10>"    android:versionName="3.5.9"    >    ...    <meta-data        android:name="UMENG_CHANNEL"        android:value="default"/>    ...<manifest>

其中versionName可以直接获取字符串,而versionCode是十六进制,所以需要进行转换。另外由于UMENG_CHANNEL的name和value不在一行,所以不能用for line in lineArray的方式,只会用下标的方式取下一行。

name=''code=''channel=''xml = os.popen('axml.sh AndroidManifest.xml').readlines()for i in range(len(xml)):    line=xml[i]#versionName    if 'versionName' in line:        name=line.split('"')[1]#versionCode    if 'versionCode' in line:        code=line[line.index('<')+1:line.index(',')]        #十六进制转十进制        code=str(int(code,16))#channel    if 'UMENG_CHANNEL' in line:        channel = xml[i+1].split('"')[1]

4. 将dex转换成jar,获取其中的class文件名称

dex转jar同样需要用网上的工具dex2jar。转换成jar包之后,就可以像读取zip文件一样读取内部文件的名称了。

os.popen('dex2jar.sh classes.dex')jfile = zipfile.ZipFile('classes_dex2jar.jar','r')count=0for filename in jfile.namelist():    #要过滤包名,不管匿名内部类    if 'com/daniel/android' in filename and '$' not in filename:        #获取类名        className=filename[filename.rindex('/')+1:filename.index('.')]        #如何类名长度小于3,同时都是小写字母,就认为是混淆之后的类        if len(className)<3 and className.islower():            count+=1

5. 显示出来

赶脚最方便的方式是做成由逗号分割的csv文件,然后用excel显示。将元组转换成由逗号分割的字符串就很简单了。需要注意的是,元组的每个元素都得是字符串

outfile.write(','.join(item)+'\n')

后续

还可以和jenkins结合,部署在服务器上。
这里写图片描述

0 0
原创粉丝点击