2. App的构建与打包:APK与IPA文件结构

好,咱们今天聊聊App的构建和打包。说白了,就是开发写完代码后,怎么变成一个你能装到手机上的文件。

我刚开始做逆向的时候,拿到一个APK第一反应就是解压。结果发现一堆乱七八糟的文件,完全不知道从哪下手。后来踩的坑多了,才慢慢摸清楚每个文件是干嘛的。

今天咱们就掰开揉碎,把Android的APK和iOS的IPA这两个东西讲明白。

2.1 Android APK文件结构

APK其实就是一个ZIP压缩包。你可以用任何解压工具打开它。我习惯用7-Zip,轻量又好用。

解压后,你会看到这些核心文件:

文件/目录 作用 我的经验
AndroidManifest.xml App的身份证,声明权限、组件、版本 逆向第一步,先看这个文件
classes.dex Dalvik字节码,App的核心逻辑 反编译主要就是搞它
resources.arsc 编译后的资源索引表 字符串、布局、图片的映射关系
lib/ Native库,.so文件 加密、核心算法常藏在这里
META-INF/ 签名信息 改完APK必须重新签名
res/ 原始资源文件 图片、布局、动画等

2.1.1 AndroidManifest.xml

这个文件是App的入口。我每次拿到一个APK,第一件事就是看它。

它告诉你:

  • App的包名是什么
  • 申请了哪些权限(比如读取联系人、定位)
  • 有哪些Activity、Service、BroadcastReceiver
  • 入口Activity是哪个

举个例子,你看到一个App申请了READ_CONTACTS权限,但它是个手电筒App。嗯,这里要注意,这很可能有问题。

注意:APK里的AndroidManifest.xml是二进制格式,不能直接用文本编辑器打开。你需要用工具反编译,比如AXMLPrinter2或apktool。

我曾经遇到过一个恶意App,它在Manifest里声明了RECEIVE_BOOT_COMPLETED权限。开机自启动,偷偷上传用户数据。这种小动作,一看Manifest就露馅了。

2.1.2 classes.dex

这是App的核心。所有的Java/Kotlin代码,最终都编译成Dalvik字节码,放在这个文件里。

为什么叫classes.dex?因为早期Android App只有一个dex文件。后来方法数超过65535,就有了多dex方案,比如classes2.dex、classes3.dex。

逆向分析时,我们主要就是反编译这个dex文件。常用的工具有:

  • jadx:我目前的主力工具,直接反编译成Java代码
  • JEB:商业工具,功能强大,但收费
  • apktool:可以反编译成smali代码,适合做修改
小技巧:如果App有多个dex文件,建议先用jadx全部加载,它会自动合并。这样你搜索类名时不会漏掉。

2.1.3 resources.arsc

这个文件是个索引表。它记录了所有资源的ID和对应的值。

比如你在代码里写R.string.app_name,实际对应的是一个数字ID。resources.arsc就是把这个ID映射到实际的字符串。

逆向时,我们经常通过这个文件来找关键字符串。比如:

  • API接口地址
  • 加密密钥
  • 错误提示信息

我有个习惯:拿到APK后,先用工具把resources.arsc里的字符串全部导出。然后搜索"http"、"key"、"secret"这些关键词。经常能发现一些开发者不小心留下的敏感信息。

2.1.4 lib目录

这个目录存放Native库,也就是.so文件。它们是用C/C++写的,编译成机器码。

为什么App要用Native代码?

  • 性能要求高(比如游戏引擎、音视频处理)
  • 复用已有的C/C++库
  • 隐藏核心逻辑(反编译dex容易,反编译so难)

lib目录下通常有多个子目录,对应不同的CPU架构:

  • armeabi-v7a:老款ARM设备
  • arm64-v8a:主流64位ARM设备
  • x86 / x86_64:模拟器常用
重点:很多App会把核心加密算法放在.so文件里。逆向so文件需要用到IDA Pro或Ghidra。这比反编译dex要难得多,但也是高级逆向工程师的必备技能。

我曾经分析过一个金融App,它的支付签名逻辑全在so里。dex里只是调用了Native方法。想绕过它的签名校验?必须把so啃下来。

2.2 iOS IPA文件结构

说完了Android,咱们看看iOS。IPA本质上也是一个压缩包,但结构完全不同。

IPA文件其实是个ZIP包,把后缀改成.zip就能解压。解压后你会看到:

文件/目录 作用 我的经验
Payload/ 核心目录,里面放.app包 所有东西都在这里
Info.plist App的配置信息 类似Android的Manifest
可执行文件 Mach-O格式,App的二进制代码 逆向的主要目标
_CodeSignature/ 代码签名 改完必须重签
iTunesArtwork App图标 没啥用,但别删

2.2.1 Payload目录

这是IPA的核心。里面只有一个.app包,名字通常和App的Bundle Identifier有关。

这个.app其实是个目录,里面包含了:

  • 可执行文件(Mach-O)
  • 资源文件(图片、音频、NIB/XIB)
  • Frameworks(动态库)
  • PlugIns(插件)

我刚开始逆向iOS App时,第一反应是直接看可执行文件。后来发现,很多App把资源文件藏在了Asset.car里。这个文件需要用专门的工具才能解包。

2.2.2 Info.plist

这个文件是iOS App的配置文件。用Xcode或文本编辑器都能打开。

它包含:

  • Bundle Identifier(唯一标识)
  • 版本号
  • 权限声明(比如相机、定位)
  • 支持的设备方向
  • URL Schemes
小技巧:逆向时,重点关注CFBundleURLSchemes。它定义了App能处理的URL协议。很多App通过URL Scheme实现App间跳转,这里经常有安全漏洞。

我记得有个社交App,它的URL Scheme里直接暴露了用户ID。你只要构造一个URL,就能直接打开某个用户的聊天界面。这种问题,一看Info.plist就能发现。

2.2.3 可执行文件

这是iOS App的核心。它是一个Mach-O格式的二进制文件。

Mach-O是苹果系统的可执行文件格式。它和Windows的PE、Linux的ELF是同一类东西。

逆向Mach-O文件,常用的工具有:

  • Hopper Disassembler:我比较喜欢用,界面友好
  • IDA Pro:功能最强大,但价格不菲
  • Ghidra:免费开源,NSA出品

Mach-O文件的结构大致如下:

  • Header:文件类型、CPU架构
  • Load Commands:加载指令,告诉系统怎么加载这个文件
  • Segments:代码段、数据段等
  • Symbol Table:符号表,函数名、变量名
注意:iOS App发布时,可执行文件会被加密。这叫FairPlay DRM。你需要先用工具解密,比如Clutch或dumpdecrypted。否则你看到的全是乱码。

我曾经花了一整天去分析一个加密的Mach-O文件,结果发现忘了先解密。嗯,这种低级错误,犯过一次就不会再犯了。

2.3 知识体系总览

说了这么多,咱们用一张图来总结一下APK和IPA的核心结构。

App文件结构总览 Android APK AndroidManifest.xml - 权限、组件声明 classes.dex - Dalvik字节码(核心逻辑) resources.arsc - 资源索引表 lib/ - Native库(.so文件) META-INF/ - 签名信息 res/ - 原始资源文件 iOS IPA Payload/ - 核心目录(.app包) Info.plist - 配置信息 可执行文件 - Mach-O格式 _CodeSignature/ - 代码签名 Frameworks/ - 动态库 Asset.car - 资源包

这张图把APK和IPA的核心文件都列出来了。你想想看,逆向分析时,我们主要就是跟这些文件打交道。

Android这边,重点看dex和so。iOS那边,重点看Mach-O和Info.plist。掌握了这些,你就知道该从哪下手了。

好了,这一章的内容就到这。记住,拿到一个App,先看它的结构,再决定分析策略。别上来就反编译,那样效率很低。


公众号:蓝海资料掘金营,微信deep3321