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

发布于 2024-09-13 05:12:27 字数 229 浏览 8 评论 0 原文

有没有办法以编程方式确定当前运行的应用程序是仅为开发而构建和签名的,还是为分发而构建的?能否确定是为应用程序商店还是临时分发而构建的?

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

任何提示表示赞赏。


看来embedded.mobileprovision文件是ASN.1格式的。

Is there a way to determine programmatically if the currently running app was built and signed for development only or whether it was built for distribution? And can one determine if was build for app store or ad hoc distribution?

Is it e.g. possibly to access the code signature and get the information from there? Or are there certain files present in one of variants that don't exist in the other ones? Is part of the bundle info? Or can it be derived from the executable file?

Any hints are appreciated.


It seems that the embedded.mobileprovision file is in ASN.1 format.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

双马尾 2024-09-20 05:12:34

我创建了一个要点来检测临时构建
请参阅: https://gist.github.com/iShawnWang/d904934efded271d83b36288562df410

AdHoc 检测具有以下 2 个条件:

1.embedded.mobileprovision 包含字段 ProvisionedDevices (Debug 和 Ad Hoc Build 包含此字段,Release 不包含)

2.它不是 DEBUG Build ,我们可以使用 #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;
}

I create a gist to detect Ad Hoc build
See : https://gist.github.com/iShawnWang/d904934efded271d83b36288562df410

AdHoc detect with following 2 conditions :

1.embedded.mobileprovision contains field ProvisionedDevices (Debug and Ad Hoc Build contains this field ,Release not)

2.it is not DEBUG Build , we can use #ifdef DEBUG to decide it

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;
}
一束光,穿透我孤独的魂 2024-09-20 05:12:33
#if (DEBUG)
#define SERVER @"aaaa.com/dev"
#else
#define SERVER @"aaa.com/pro"
#endif

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

但我不知道临时模式或生产模式,除非使用配置文件名称

#if (DEBUG)
#define SERVER @"aaaa.com/dev"
#else
#define SERVER @"aaa.com/pro"
#endif

that's the way i distinguish the debug and release mode ,

but i have no idea for adhoc or production unless use the provision profile name

源来凯始玺欢你 2024-09-20 05:12:32

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

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 部分,其中包含有关分发类型(开发人员、临时、App Store)的所有答案。

I've extracted an embedded.mobileprovision file and pasted into an online ASN.1 viewer (e.g. http://www.geocities.co.jp/SiliconValley-SanJose/3377/asn1JS.html), and that's what a got:

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]

With this and some ASN.1 knowledge, your explanation makes perfect sense.

The interesting part is the octet string starting 3c3f786d6c. That's the XML part in Apple's property list format that contains all the answers about the distribution type (developer, ad-hoc, App Store).

诺曦 2024-09-20 05:12:30

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

  • 有点解析起来很痛苦,因为它是一个签名的 plist(PKCS#7 签名数据,根据 openssl asn1parse -inform der),但一个糟糕的黑客是只寻找
  • 开发包含 UDID 和 get-task-allow
  • Ad Hoc 发行版包含 UDID(且 get-task-allow=false)
  • App Store 发行版不包含UDID。

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

  • 开发版本包含 get-task-allow
  • Ad Hoc 和 App Store 版本包含 get-task-allow

我认为 Ad Hoc 版本和 App Store 版本之间的权利没有区别。

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

安全考虑

这些都不是很难规避的。对于第一种方法,应用程序只需“调配”-[NSBundle pathForResource:ofType:]。第二种方法有点困难,具体取决于您使用什么 API 来读取文件。

The easiest way to check is to look at embedded.mobileprovision ([[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil]):

  • It's a bit of a pain to parse since it's a signed plist (PKCS#7 signed data, according to openssl asn1parse -inform der), but a bad hack is to just look for <plist and </plist>.
  • Development contains UDIDs and <key>get-task-allow</key><true/>
  • Ad Hoc distribution contains UDIDs (and get-task-allow=false)
  • App Store distribution contains no UDIDs.

The other thing you can check is the entitlements embedded in the executable (otool -l lists it as LC_CODE_SIGNATURE). Parsing this is even more tedious (you need to parse the Mach-O header and load commands, and for "universal" binaries which are now the default, you'll need to check the currently-loaded architecture or all architectures).

  • Development builds contain <key>get-task-allow</key><true/>
  • Ad Hoc and App Store builds contain <key>get-task-allow</key><false/>

I don't think the entitlements distinguish between Ad Hoc and App Store builds.

Apart from those and the certificate it's signed with, there's no difference between Development/Ad Hoc/App Store apps (there are a few other things in the entitlements/provisioning profile, but nothing more reliable that I can think of).

Security considerations

Neither of these are that difficult to circumvent. For the first method, the app could just "swizzle" -[NSBundle pathForResource:ofType:]. The second method is a bit more difficult depending on what API you use to read the file.

巷子口的你 2024-09-20 05:12:30

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

编辑:

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

openssl asn1parse -inform DEM -in *Mobile_Provision_File* -strparse 54 is the easiest way to access the data that I've found.

EDIT:

security cms -D -i *Mobile_Provision_File* is actually easier. The openssl command leaves some garbage in the output.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文