Meituan-Dianping / walle

Android Signature V2 Scheme签名下的新一代渠道包打包神器

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

zip里添加注释,然后用apksigner签名,目前会抛出异常

zuijinbuzai opened this issue · comments

apksigner校验ok,可正常安装到7.0设备,导出也带注释信息

您要添加什么注释信息? 我们目前觉得注释区没啥需求 有注释的apk会直接报错,不生成渠道包

1.我要对接入我们sdk的应用,进行2次打入渠道号,那么这种情况下,可能会出问题(不可控)
2.也可能出现分发方提供sdk,我们接入,我们会有自己的渠道号。签名过后的包给对方,对方会再次写入他们的渠道号。(也就是2个渠道号,分别是我写入的,和对方写入的)针对这种情况是否能提供扩充?

注释区写入信息后 v2的签名会有问题 详见博客
如果你使用walle的话,分发方也必须使用兼容v2签名的渠道方式写入渠道 否则需要重新签名

签名是针对apk的 所以你说的sdk我并不是特别理解。
如果是多个渠道的号的话,目前并不支持,但有一个解决办法:
extraInfo是可以多存储的(key必须唯一),你可以放置类似subchannel这种key,然后value写入即可

或者你的channel直接写成 meituan-ceshi-xiaomi ?

我在生成apk后,再写入注释,再v2签名,把这个作为母包。不是先v2签名,再写入注释,不确定有些应用会不会这么操作。

比如分发平台,会让对接的应用使用平台的提供的sdk,平台拿到包后,会再次打入渠道号,而应用自己也会有渠道号的。

所以比较理想的情况注释不要抛出异常,渠道工具提供另外的id写入渠道,不覆盖对方的渠道号。
使用extraInfo会限定了对方写入格式。当然也要判断对方的签名方式

分开两种你说的情况:

  • 你的注释: 是否可以完全用extraInfo的方式来替代?
  • 应用二次打渠道号:美团是提供打渠道号的服务器接口,打子渠道号写在另一个字段里。

另:以前是否使用过美团的一代打包呢? 一代时候你们怎么处理的?

主要包是别人的,行为不可控,(怕接入的app这么做)。
以前也是看了你们博客,后台或服务器按此原理对所有接入sdk的包META-INF写入文件。

以前也是看了你们博客,后台或服务器按此原理对所有接入sdk的包META-INF写入文件。

那现在也可以啊 我们提供jar给服务器写入能力,meta-inf可以干的你们都可以写啊。 我不清楚你纠结的啥》
如果行为不可控,v2签名估计都保证不了,你就无法接入walle。 如果是公司内部多个部门,那就协商看什么时间一起换一下?
技术点上不存在问题吧。

对于注释区的话,短期内应该没有提供能力的打算,欢迎给我们提交pr吧

注释区我来改改吧

多次写入渠道待定吧

@GavinCT 不知道第二代稳不稳定啊? 刚刚接到多渠道打包的需求,前段时间研究了一代,然后发现有个问题是接入的友盟SDK等,读取的渠道包是写死在AndroidManifest.xml中的 UMENG_CHANNEL 字段,不能去更改,因此打算用自己公司开发的大数据SDK,然后在代码中去读取美团方案弄出来的渠道包。
现在一看技术文档,发现第二代出来了,第二代和第一代应该是一样的,友盟等SDK无法自动识别多渠道打包后的渠道包名吧。 现在有两个疑问点:
1、不知道针对友盟SDK等写死在AndroidManifest.xml中配置有没有好的方案呢?
2、第二代多渠道打包,看提交日期是刚提交不久,不知道稳不稳定?

@ouyangpeng 你应该单独开issue。。。

  1. 对于美团打包方案来说,友盟sdk解决方案一直是自己在代码里读取set进去
  2. 稳定

@GavinCT 已经单独开了issue

@ouyangpeng 友盟SDK可以用AnalyticsConfig.setChannel(channelStr);的方式设置渠道号的。xml和代码这两种方式,两者取其一。你文档都不看的么。

@GavinCT 对于注释的处理,你可以看google apksigner的ZipUtils里面的方法,其实就是倒着找EOCD的signature,很简单

是啊 不难啊 最近在忙啊 再等等吧

也欢迎各位提交pr 一起完善啊 @truebit

哈哈,我嫌弃Java处理二进制的方式(ByteBuffer真难用),用python写了个脚本处理渠道包的

哎 我们上班基本也都在忙自己的 最近的代码提交都是周五晚上或者周六的。。。 所以这个感觉不是很重要紧急的问题就拖了几个版本 我们尽快完善起来

有空的话我给你提个java版的PR 😉 下面是python版的

with open(self.apk_file_path, 'rb') as fp:
    scan_offset = self.apk_size - ZIP_EOCD_REC_MIN_SIZE  # try to get End of central directory signature
    if scan_offset < 0:
        raise APKSignV2ParseError("File too short to be a zip file: "
                                  + self.apk_size)
    stop_offset = scan_offset - MAX_COMMENT_SIZE  # largest comment size
    if stop_offset < 0:
        stop_offset = 0
    while True:
        fp.seek(scan_offset)
        if self.to_le_int(fp.read(4)) == ZIP_EOCD_REC_SIG:  # End of central directory signature
            fp.seek(scan_offset + 16)  # Offset of start of central directory at index 16 from EOCD signature
            return self.to_le_int(fp.read(4))
        scan_offset -= 1
        if scan_offset < stop_offset:
            raise APKSignV2ParseError("EOCD not found; not a zip file?")

是不是觉得python读二进制简单多了🤣

commented

大公司是不是都有开源kpi的要求哈

。。。你想多了 @caishengyan

@caishengyan 开源完全看个人对开源的态度。而且越大的公司代码开源越有一堆政策、版权、安全等等的考虑,更加麻烦。
我本人特别支持开源。如果公司允许,我可以把我的python版开源233

@truebit 看了友盟文档,之前已经设置好了。

1.1.3版本已经发布,修复此问题 @zuijinbuzai

commented

WalleChannelReader.getChannel(this.getApplicationContext());
这个为什么返回空啊,在AndroidManifest.xml中有设置默认值:

@SunnyLy 问题记得以后单开issue
你还是没看明白walle的使用。 walle和清单文件无关啊 你设置值又有啥用。 仔细看下readme

我们运营总监要求,要集成到PHP后台提供分渠道打包的功能,集成到公司的OA里,方便大家操作。
请问这个插件可以改成支持PHP后台的吗?麻烦提供一下源码和思路,谢谢!

@qq363685855 自己了解APK v2 sign的原理,用各种语言都可以实现。
apk-before-after-signing
原理很简单,APK v2 signing block这块代码是不会被安卓验证的,把你的渠道号写到这里就行了。
apk sign block的定义在这里:https://source.android.com/security/apksigning/v2?hl=zh-cn#apk-signature-scheme-v2-block-format

java.lang.NoSuchMethodError: No virtual method a()Ljava/util/Iterator; in class Lorg/json/JSONObject; or its super classes (declaration of 'org.json.JSONObject' appears in /system/framework/core-libart.jar)
at com.meituan.android.walle.ChannelReader.b(SourceFile:47)
at com.meituan.android.walle.ChannelReader.a(SourceFile:25)
at com.meituan.android.walle.WalleChannelReader.a(SourceFile:56)