使用 Adobe AIR 重新打包 APK
Repackage APK with Adobe AIR
有一个 Android Flash 游戏是用 Adobe AIR 打包的,但它不再适用于 Android 7 以上的版本。我想知道是否可以重新打包这个游戏使用 HARMAN's Adobe AIR?
我已经下载 HARMAN's Adobe AIR 并尝试使用 ADT 包命令 重新打包应用程序。我使用了 APK 的 assets/META-INF/AIR/
文件夹中的 application.xml
文件。但是,此应用程序使用扩展,ADT 似乎需要 ANE(AIR 本机扩展)文件,还是有其他方式?
我无法在线找到 ANE 文件。但一些中国黑客能够重新打包该应用程序,在 Android 10 中工作,并且文件夹 assets/META-INF/AIR/extensions
文件夹与原始 apk 相比没有任何变化。但是,文件夹 lib/armeabi-v7a
中的文件已更新,包括一个名为 libX86Bridge.so
.
的新文件
原始应用程序使用的扩展程序是:
- com.adobe.ane.social
- com.milkmangames.extensions.AndroidIAB
- com.chartboost.plugin.air
- com.milkmangames.extensions.CoreMobile
- com.jirbo.airadc.AirAdColony
- com.milkmangames.extensions.GoViral
所以我终于能够重新打包 APK,并且它适用于最新的 Android 版本!
首先,我用存档管理器打开APK文件(APK是一个ZIP文件),然后使用dex2jar工具将APK里面的classes.dex
文件转换成JAR文件.在 JAR 文件(也是一个 ZIP 文件)中是来自应用程序使用的 AIR Native Extensions 的已编译 Java 类。
然后,在 Adobe AIR by HARMAN 的 bin
目录中,我为每个扩展创建了一个目录:
AIRSDK_Windows\bin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral
可以在 APK 中的路径 /assets/META-INF/AIR/extensions/
.
中找到解压后的扩展 ANE
对于每个扩展名,将 catalog.xml
和 library.swf
添加到 ZIP 文件中,并将 ZIP 扩展名重命名为 SWC(例如:com.adobe.ane.social.swc
)。然后,将 SWC 文件放入相应扩展程序的目录中。
在 APK 中每个扩展的目录中,有一个路径 META-INF/ANE/
,其中可以找到文件 extension.xml
和其他文件(例如:/assets/META-INF/AIR/extensions/com.adobe.ane.social/META-INF/ANE/
)。我将这些目录中的所有文件放在我在 bin
目录中创建的相应扩展的目录中。例如,对于 com.chartboost.plugin.air
扩展名,目录结构如下所示:
AIRSDK_Windows\bin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
│ ├── com.chartboost.plugin.air.swc
│ ├── extension.xml
│ ├── Android-ARM
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral
我打开了 extension.xml
文件,这些是它的内容:
<extension xmlns="http://ns.adobe.com/air/extension/16.0">
<id>com.chartboost.plugin.air</id>
<versionNumber>5.5.0</versionNumber>
<platforms>
<platform name="Android-ARM">
<applicationDeployment>
<nativeLibrary>libChartboostAir.jar</nativeLibrary>
<initializer>com.chartboost.plugin.air.ChartboostExtension</initializer>
<finalizer>com.chartboost.plugin.air.ChartboostExtension</finalizer>
</applicationDeployment>
</platform>
<platform name="iPhone-ARM">
<applicationDeployment>
<nativeLibrary>libChartboostAir.a</nativeLibrary>
<initializer>ChartboostExtInitializer</initializer>
<finalizer>ChartboostExtFinalizer</finalizer>
</applicationDeployment>
</platform>
<platform name="default">
<applicationDeployment/>
</platform>
</platforms>
</extension>
由于我没有为 iPhone-ARM
打包游戏,也没有 libChartboostAir.a
文件,我评论说 platform
使用 XML 评论阻止 <!-- -->
.
我们可以看到有一个 default
平台(我注意到所有扩展都有一个)。因此,我为 default
平台创建了一个目录,并将 library.swf
从 Android-ARM
目录复制到该目录。然后将两个目录放在 platform
目录中。目录结构现在如下所示:
AIRSDK_Windows\bin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
│ ├── com.chartboost.plugin.air.swc
│ ├── extension.xml
│ ├── platform
│ │ ├── Android-ARM
│ │ │ ├── library.swf
│ │ │ ├── <other bunch of files>
│ │ ├── default
│ │ │ ├── library.swf
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral
然后,从我们一开始得到的JAR文件(由classes.dex
转换而来),我得到了所有与com.chartboost.plugin.air
相关的类,并将它们放在一个ZIP压缩包中命名为 libChartboostAir.jar
。然后我将 libChartboostAir.jar
放在 Android-ARM
目录中。
最后,对于这个扩展,我运行下面的命令来生成ANE文件:
..\adt.bat -package -target ane com.chartboost.plugin.air.ane extension.xml -swc com.chartboost.plugin.air.swc -platform Android-ARM -C platform/Android-ARM . -platform default -C platform/default library.swf
我按照上述步骤为其他扩展生成了 ANE 文件。最后,JAR 文件中有一些 类(从 classes.dex
生成)我没有从任何扩展名放入 JAR 文件中,因为我不知道它们属于哪里。所以,我只是将它们放在 运行dom 扩展的 JAR 文件中。这不是问题,因为重要的是所有 类 最终都被放置在新的 classes.dex
文件中,使用与原始文件相同的目录结构。
编译完所有 ANE 文件后,我在 bin
目录中为我要重新打包的应用程序创建了一个目录。
在原始 APK 的 assets
目录中,有应用程序的 SWF 文件和一个包含应用程序图标的 _Pic_Gen
目录。我把它们都放在我刚刚创建的目录中。在原始 APK 的 /assets/META-INF/AIR/
目录中有一个 application.xml
文件和一个 extensions
目录(带有解压的 ANE)。我将 application.xml
文件放在我为 bin
目录中的应用程序创建的目录中。在这个目录中,我还创建了一个 extensions
目录,并将编译后的 ANE 文件放在里面。因此,此应用程序的目录结构现在如下所示:
AIRSDK_Windows\bin
├── MyApp
│ ├── application.xml
│ ├── _Pic_Gen
│ ├── MyApp.swf
│ ├── extensions
│ │ ├── com.adobe.ane.social.ane
│ │ ├── com.milkmangames.extensions.AndroidIAB.ane
│ │ ├── com.chartboost.plugin.air.ane
│ │ ├── com.milkmangames.extensions.CoreMobile.ane
│ │ ├── com.jirbo.airadc.AirAdColony.ane
│ │ └── com.milkmangames.extensions.GoViral.ane
为了支持Android11(目前最新的),我把application.xml
里面的manifest里面的targetSdkVersion
改成了30。 Android版本与SDK关联:https://developer.android.com/studio/releases/platforms
我也把<application xmlns="http://ns.adobe.com/air/application/17.0">
改成了<application xmlns="http://ns.adobe.com/air/application/33.1">
,这样就用最新的Flash Player版本了(33.1是HARMAN的)。
然后,我使用 OpenSSL 创建了一个自签名证书(为此我使用了 Linux):
openssl req -newkey rsa:2048 -x509 -keyout cakey.pem -out cacert.pem -days 10000
# entered my password
openssl pkcs12 -export -in cacert.pem -inkey cakey.pem -out myapp.p12
最后,我可以打包新的 APK,使用:
..\adt.bat -package -target apk -storetype pkcs12 -keystore myapp.p12 MyApp.apk application.xml -extdir extensions MyApp.swf _Pic_Gen
# entered certificate's password
编辑 2021-05-19(编辑 2022-02-19:最新的 Adobe AIR 不再需要此步骤哈曼。)
但是,对于 Android 11 及更高版本,现在必须使用 APK 签名方案 v2 或更高版本对 APK 进行签名(参见:)。使用 apksigner
(在 Android SDK 中可用),您可以按如下方式执行此操作:
C:\Users\<user>\AppData\Local\Android\Sdk\build-tools\<version>\apksigner.bat sign -v --out MyApp_v2signed.apk --ks myapp.p12 MyApp.apk
然后生成了 APK,我可以在最近的 Android 版本上玩游戏。
编辑 2021-06-25
显然在某些设备上打开 APK 时会出现错误,提示“解析此包时出现问题”。
我在使用 Android Studio 分析 APK 时遇到的错误是:INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED
然后我在 AIR SDK 中遇到了 this issue。打开 AIRSDK_Windows\lib\adt.cfg
显示了注释行:
#UncompressedExtensions=emd,tfl,tflite,pb
我取消注释并向其添加 arsc
扩展名,这是 Android Studio 抱怨的文件 resources.arsc 的扩展名。这解决了使用新配置重新打包 APK 后的问题。
编辑 2022-02-11
对于最新的 Adobe AIR,如果不想使用 Android SDK 进行构建,则应将以下行添加到 <android>
部分下的 application.xml
文件中。参见:https://github.com/airsdk/Adobe-Runtime-Support/issues/1527#issuecomment-1007293682
<BuildLegacyAPK>true</BuildLegacyAPK>
另一种选择是使用 Android SDK 进行构建,在这种情况下,应在文件 AIRSDK_Windows\lib\adt.cfg
中添加以下行(替换为正确的路径):
AndroidPlatformSDK=C:/Users/<user>/AppData/Local/Android/Sdk
JAVA_HOME=C:/Program Files/Java/jdk-11.0.14
注意必须使用Java11以上
此外,Android 12 现在要求具有 Intent 过滤器的接收器具有属性 android:exported
。示例:
<receiver android:name="com.milkmangames.extensions.android.CMBootReceiver" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
有一个 Android Flash 游戏是用 Adobe AIR 打包的,但它不再适用于 Android 7 以上的版本。我想知道是否可以重新打包这个游戏使用 HARMAN's Adobe AIR?
我已经下载 HARMAN's Adobe AIR 并尝试使用 ADT 包命令 重新打包应用程序。我使用了 APK 的 assets/META-INF/AIR/
文件夹中的 application.xml
文件。但是,此应用程序使用扩展,ADT 似乎需要 ANE(AIR 本机扩展)文件,还是有其他方式?
我无法在线找到 ANE 文件。但一些中国黑客能够重新打包该应用程序,在 Android 10 中工作,并且文件夹 assets/META-INF/AIR/extensions
文件夹与原始 apk 相比没有任何变化。但是,文件夹 lib/armeabi-v7a
中的文件已更新,包括一个名为 libX86Bridge.so
.
原始应用程序使用的扩展程序是:
- com.adobe.ane.social
- com.milkmangames.extensions.AndroidIAB
- com.chartboost.plugin.air
- com.milkmangames.extensions.CoreMobile
- com.jirbo.airadc.AirAdColony
- com.milkmangames.extensions.GoViral
所以我终于能够重新打包 APK,并且它适用于最新的 Android 版本!
首先,我用存档管理器打开APK文件(APK是一个ZIP文件),然后使用dex2jar工具将APK里面的classes.dex
文件转换成JAR文件.在 JAR 文件(也是一个 ZIP 文件)中是来自应用程序使用的 AIR Native Extensions 的已编译 Java 类。
然后,在 Adobe AIR by HARMAN 的 bin
目录中,我为每个扩展创建了一个目录:
AIRSDK_Windows\bin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral
可以在 APK 中的路径 /assets/META-INF/AIR/extensions/
.
对于每个扩展名,将 catalog.xml
和 library.swf
添加到 ZIP 文件中,并将 ZIP 扩展名重命名为 SWC(例如:com.adobe.ane.social.swc
)。然后,将 SWC 文件放入相应扩展程序的目录中。
在 APK 中每个扩展的目录中,有一个路径 META-INF/ANE/
,其中可以找到文件 extension.xml
和其他文件(例如:/assets/META-INF/AIR/extensions/com.adobe.ane.social/META-INF/ANE/
)。我将这些目录中的所有文件放在我在 bin
目录中创建的相应扩展的目录中。例如,对于 com.chartboost.plugin.air
扩展名,目录结构如下所示:
AIRSDK_Windows\bin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
│ ├── com.chartboost.plugin.air.swc
│ ├── extension.xml
│ ├── Android-ARM
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral
我打开了 extension.xml
文件,这些是它的内容:
<extension xmlns="http://ns.adobe.com/air/extension/16.0">
<id>com.chartboost.plugin.air</id>
<versionNumber>5.5.0</versionNumber>
<platforms>
<platform name="Android-ARM">
<applicationDeployment>
<nativeLibrary>libChartboostAir.jar</nativeLibrary>
<initializer>com.chartboost.plugin.air.ChartboostExtension</initializer>
<finalizer>com.chartboost.plugin.air.ChartboostExtension</finalizer>
</applicationDeployment>
</platform>
<platform name="iPhone-ARM">
<applicationDeployment>
<nativeLibrary>libChartboostAir.a</nativeLibrary>
<initializer>ChartboostExtInitializer</initializer>
<finalizer>ChartboostExtFinalizer</finalizer>
</applicationDeployment>
</platform>
<platform name="default">
<applicationDeployment/>
</platform>
</platforms>
</extension>
由于我没有为 iPhone-ARM
打包游戏,也没有 libChartboostAir.a
文件,我评论说 platform
使用 XML 评论阻止 <!-- -->
.
我们可以看到有一个 default
平台(我注意到所有扩展都有一个)。因此,我为 default
平台创建了一个目录,并将 library.swf
从 Android-ARM
目录复制到该目录。然后将两个目录放在 platform
目录中。目录结构现在如下所示:
AIRSDK_Windows\bin
├── com.adobe.ane.social
├── com.milkmangames.extensions.AndroidIAB
├── com.chartboost.plugin.air
│ ├── com.chartboost.plugin.air.swc
│ ├── extension.xml
│ ├── platform
│ │ ├── Android-ARM
│ │ │ ├── library.swf
│ │ │ ├── <other bunch of files>
│ │ ├── default
│ │ │ ├── library.swf
├── com.milkmangames.extensions.CoreMobile
├── com.jirbo.airadc.AirAdColony
├── com.milkmangames.extensions.GoViral
然后,从我们一开始得到的JAR文件(由classes.dex
转换而来),我得到了所有与com.chartboost.plugin.air
相关的类,并将它们放在一个ZIP压缩包中命名为 libChartboostAir.jar
。然后我将 libChartboostAir.jar
放在 Android-ARM
目录中。
最后,对于这个扩展,我运行下面的命令来生成ANE文件:
..\adt.bat -package -target ane com.chartboost.plugin.air.ane extension.xml -swc com.chartboost.plugin.air.swc -platform Android-ARM -C platform/Android-ARM . -platform default -C platform/default library.swf
我按照上述步骤为其他扩展生成了 ANE 文件。最后,JAR 文件中有一些 类(从 classes.dex
生成)我没有从任何扩展名放入 JAR 文件中,因为我不知道它们属于哪里。所以,我只是将它们放在 运行dom 扩展的 JAR 文件中。这不是问题,因为重要的是所有 类 最终都被放置在新的 classes.dex
文件中,使用与原始文件相同的目录结构。
编译完所有 ANE 文件后,我在 bin
目录中为我要重新打包的应用程序创建了一个目录。
在原始 APK 的 assets
目录中,有应用程序的 SWF 文件和一个包含应用程序图标的 _Pic_Gen
目录。我把它们都放在我刚刚创建的目录中。在原始 APK 的 /assets/META-INF/AIR/
目录中有一个 application.xml
文件和一个 extensions
目录(带有解压的 ANE)。我将 application.xml
文件放在我为 bin
目录中的应用程序创建的目录中。在这个目录中,我还创建了一个 extensions
目录,并将编译后的 ANE 文件放在里面。因此,此应用程序的目录结构现在如下所示:
AIRSDK_Windows\bin
├── MyApp
│ ├── application.xml
│ ├── _Pic_Gen
│ ├── MyApp.swf
│ ├── extensions
│ │ ├── com.adobe.ane.social.ane
│ │ ├── com.milkmangames.extensions.AndroidIAB.ane
│ │ ├── com.chartboost.plugin.air.ane
│ │ ├── com.milkmangames.extensions.CoreMobile.ane
│ │ ├── com.jirbo.airadc.AirAdColony.ane
│ │ └── com.milkmangames.extensions.GoViral.ane
为了支持Android11(目前最新的),我把application.xml
里面的manifest里面的targetSdkVersion
改成了30。 Android版本与SDK关联:https://developer.android.com/studio/releases/platforms
我也把<application xmlns="http://ns.adobe.com/air/application/17.0">
改成了<application xmlns="http://ns.adobe.com/air/application/33.1">
,这样就用最新的Flash Player版本了(33.1是HARMAN的)。
然后,我使用 OpenSSL 创建了一个自签名证书(为此我使用了 Linux):
openssl req -newkey rsa:2048 -x509 -keyout cakey.pem -out cacert.pem -days 10000
# entered my password
openssl pkcs12 -export -in cacert.pem -inkey cakey.pem -out myapp.p12
最后,我可以打包新的 APK,使用:
..\adt.bat -package -target apk -storetype pkcs12 -keystore myapp.p12 MyApp.apk application.xml -extdir extensions MyApp.swf _Pic_Gen
# entered certificate's password
编辑 2021-05-19(编辑 2022-02-19:最新的 Adobe AIR 不再需要此步骤哈曼。)
但是,对于 Android 11 及更高版本,现在必须使用 APK 签名方案 v2 或更高版本对 APK 进行签名(参见:)。使用 apksigner
(在 Android SDK 中可用),您可以按如下方式执行此操作:
C:\Users\<user>\AppData\Local\Android\Sdk\build-tools\<version>\apksigner.bat sign -v --out MyApp_v2signed.apk --ks myapp.p12 MyApp.apk
然后生成了 APK,我可以在最近的 Android 版本上玩游戏。
编辑 2021-06-25
显然在某些设备上打开 APK 时会出现错误,提示“解析此包时出现问题”。
我在使用 Android Studio 分析 APK 时遇到的错误是:INSTALL_PARSE_FAILED_RESOURCES_ARSC_COMPRESSED
然后我在 AIR SDK 中遇到了 this issue。打开 AIRSDK_Windows\lib\adt.cfg
显示了注释行:
#UncompressedExtensions=emd,tfl,tflite,pb
我取消注释并向其添加 arsc
扩展名,这是 Android Studio 抱怨的文件 resources.arsc 的扩展名。这解决了使用新配置重新打包 APK 后的问题。
编辑 2022-02-11
对于最新的 Adobe AIR,如果不想使用 Android SDK 进行构建,则应将以下行添加到 <android>
部分下的 application.xml
文件中。参见:https://github.com/airsdk/Adobe-Runtime-Support/issues/1527#issuecomment-1007293682
<BuildLegacyAPK>true</BuildLegacyAPK>
另一种选择是使用 Android SDK 进行构建,在这种情况下,应在文件 AIRSDK_Windows\lib\adt.cfg
中添加以下行(替换为正确的路径):
AndroidPlatformSDK=C:/Users/<user>/AppData/Local/Android/Sdk
JAVA_HOME=C:/Program Files/Java/jdk-11.0.14
注意必须使用Java11以上
此外,Android 12 现在要求具有 Intent 过滤器的接收器具有属性 android:exported
。示例:
<receiver android:name="com.milkmangames.extensions.android.CMBootReceiver" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>