代码之家  ›  专栏  ›  技术社区  ›  Codo

如何在运行时确定应用程序是用于开发、应用程序存储还是临时分发?

  •  29
  • Codo  · 技术社区  · 14 年前

    有没有一种方法可以通过编程确定当前运行的应用程序是为开发而构建和签名的,还是为分发而构建的?是否可以确定是为应用商店还是临时发布而构建的?

    是否可能访问代码签名并从中获取信息?或者在其中一个变体中是否存在其他变体中不存在的某些文件?是捆绑信息的一部分吗?或者它可以从可执行文件派生?

    如有任何提示,我们将不胜感激。


    embedded.mobileProvision文件似乎是ASN.1格式。

    5 回复  |  直到 8 年前
        1
  •  29
  •   tc.    12 年前

    最简单的检查方法是 embedded.mobileprovision ( [[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil] ):

    • 因为它是一个有符号的plist(pkcs 7有符号数据,根据 openssl asn1parse -inform der 但一个糟糕的黑客行为就是 <plist </plist> .
    • 开发包含UDID和 <key>get-task-allow</key><true/>
    • 临时分发包含UDID(并且get task allow=false)
    • 应用商店分发不包含UDID。

    您可以检查的另一件事是嵌入在可执行文件中的权利( otool -l 把它列为 LC_CODE_SIGNATURE )解析这一点更加繁琐(您需要解析mach-o头文件和加载命令,对于现在默认的“通用”二进制文件,您需要检查当前加载的体系结构或所有体系结构)。

    • 开发构建包含 <key>获取任务允许</key><true/>
    • 临时和应用商店版本包含 <key>get-task-allow</key><false/>

    我不认为这些权利可以区分临时版本和应用商店版本。

    除了这些和它签署的证书,开发/临时/应用商店应用程序之间没有区别(在授权/供应配置文件中还有其他一些东西,但没有比我能想到的更可靠的东西)。

    安全注意事项

    这两者都不难规避。对于第一种方法,应用程序可能只是“狂饮” -[NSBundle pathForResource:ofType:] . 第二种方法有点困难,这取决于您使用什么API来读取文件。

        2
  •  12
  •   Brian King    13 年前

    openssl asn1parse -inform DEM -in *Mobile_Provision_File* -strparse 54 是访问我找到的数据的最简单方法。

    编辑:

    security cms -D -i *Mobile_Provision_File* 实际上更容易。openssl命令在输出中留下一些垃圾。

        3
  •  2
  •   Codo    14 年前

    我提取了一个embedded.mobileProvision文件并粘贴到一个在线ASN.1查看器中(例如 http://www.geocities.co.jp/SiliconValley-SanJose/3377/asn1JS.html ,这就是A所得到的:

    SEQUENCE {
       OBJECTIDENTIFIER 1.2.840.113549.1.7.2 (signedData)
       [0] {
          SEQUENCE {
             INTEGER 1
             SET {
                SEQUENCE {
                   OBJECTIDENTIFIER 1.3.14.3.2.26
                   NULL 
                }
             }
             SEQUENCE {
                OBJECTIDENTIFIER 1.2.840.113549.1.7.1 (data)
                [0] {
                   OCTETSTRING 3c3f786d6c20766 ... 6c6973743e0a
                }
             }
             [0] {
                SEQUENCE {
                   SEQUENCE {
                      [0] {
                         INTEGER 2
                      }
     ... [much more]
    

    有了这些和一些ASN.1知识,您的解释就完全有意义了。

    有趣的部分是以3c3f786d6c开头的八位字节字符串。这是Apple属性列表格式的XML部分,其中包含有关分发类型的所有答案(开发人员、即席、应用商店)。

        4
  •  0
  •   chings228    11 年前
    #if (DEBUG)
    #define SERVER @"aaaa.com/dev"
    #else
    #define SERVER @"aaa.com/pro"
    #endif
    

    这就是我区分调试和发布模式的方法,

    但是我不知道是临时的还是生产的,除非使用provision profile名称

        5
  •  0
  •   Shawn Wang    8 年前

    我创建了一个Gist来检测临时构建
    见: https://gist.github.com/iShawnWang/d904934efded271d83b36288562df410

    有以下两种情况的临时检测:

    1。 embedded.mobileprovision 包含字段 ProvisionedDevices (调试和临时生成包含此字段,不发布)

    2.它不是调试构建,我们可以使用 #ifdef DEBUG 决定它

    NS_INLINE BOOL isAdHoc(){
        BOOL isAdHoc = NO;
        BOOL isDebug;
    
    #ifdef DEBUG
        isDebug=YES;
    #else
        isDebug=NO;
    #endif
    
        NSData *data=[NSData dataWithContentsOfURL:[[NSBundle mainBundle]URLForResource:@"embedded" withExtension:@"mobileprovision"]];
        NSString *str=[[NSString alloc]initWithData:data encoding:NSISOLatin1StringEncoding];
        NSRange rangeOfDevicesUDIDs = [str rangeOfString:@"ProvisionedDevices"];
    
        isAdHoc = rangeOfDevicesUDIDs.location!=NSNotFound && !isDebug;
        return isAdHoc;
    }