将代码注入 APK
Posted
技术标签:
【中文标题】将代码注入 APK【英文标题】:Injecting code into APK 【发布时间】:2011-08-15 07:47:50 【问题描述】:我知道你可以使用 apktool 反编译代码并重新编译它,但我的问题是你如何能够将大量代码注入 apk 并执行它。
我假设亚马逊的 appstore drm 正在这样做,因为他们说他们正在用自己的代码包装 apk,一旦你反编译该 apk,你就会看到他们在那里添加了自己的类 com.amazon 等。
他们是如何做到这一点的?
【问题讨论】:
嗯,与 android Market 提交不同,开发者提交给亚马逊的 APK 没有签名。所以这是一个开始。 对,所以亚马逊在修改 apk 后使用自己的证书对其进行签名,或者我假设 【参考方案1】:我认为这篇文章:http://www.bulbsecurity.com/backdooring-apks-programmatically-2/ 非常详细地描述了如何注入类。我已经按照自己的步骤进行操作,可以确认它有效,唯一的缺点是 apk 密钥会改变,亚马逊显然就是这种情况。
至于在现有类中注入代码,这也可以通过对smali的一点了解来完成(我也做过有限规模的)。
【讨论】:
【参考方案2】:有一个 Python 库/工具 paraspace(我的小项目),可以帮助您将一个或多个类从 DEX 文件注入到另一个文件中。它将给定类的代码插入到目标 DEX 文件中,并将所有调用类的调用重定向到另一个类。因此,您可以实现 java.io.File 的派生,并将 File 的所有调用替换为派生。
paraspace 在http://hg.assembla.com/paraspace 可用,您可以使用 hg 检索它。 它仍然不成熟,但对于简单的例子来说是可行的。当你有 paraspace 的副本时,你可以尝试以下命令。
PYTHONPATH=`pwd` python examples/inject_redir.py data/suffile.dex \
'Lcom/codemud/fakefile/fakefile;' data/helloworld.dex 'Ljava/io/File;' \
output.dex
这个命令会从 sufile.dex 中读取 com.codemud.fakefile.fakefile 类并注入到 helloworld.dex 中,并作为 output.dex 写出来。所有对 java.io.File 的调用都将被 com.codemud.fakefile.fakefile 的调用方法替换。 helloworld.dex和sufile.dex的源码在这里。
http://www.codemud.net/~thinker/downloads/paraspace-milestone1-sample.tar.gz
仅供参考
【讨论】:
这篇文章非常有帮助我正在尝试通过将我的代码注入任何第三方 apk 来包装 apk。我已经从 repo 中签出你的代码并尝试运行脚本,但是我在 import 语句“from paraspace.dexfile import DEXFile,DEXFile_linked”时遇到错误,似乎找不到这个模块你能帮我这个错误吗我不熟悉 python 【参考方案3】:只是为了好玩,我从亚马逊商店下载了一个 apk(我今晚之前从未使用过)并反编译它。您不会在清单中找到太多内容,但在 smali 树中有一个完整的 Amazon 类文件夹。 Amazon 使用的机制在很大程度上超出了我非常有限的理解,但我可以为您指出一些数据。
更新:这些应用需要安装亚马逊应用商店 apk 才能运行,因此下面的类使用一些亚马逊活动来检查 drm。
方法:
$apktool d xxx.apk
$cd xxx/smali
$grep -RHin 'amazon' *
调查结果:
首先,你可能想看看
.class public Lcom/amazon/mas/kiwi/util/ApkHelpers;
及其方法:
.method public static getApkSignature(Ljava/lang/String;)[B
.method private static getCodeSigners(Ljava/util/jar/JarFile;)[Ljava/security/CodeSigner;
.method public static getContentID(Ljava/util/jar/JarFile;)Ljava/lang/String;
.method public static getContentIDFromName(Ljava/lang/String;)Ljava/lang/String;
.method private static getFirstSigningCert(Ljava/util/jar/JarFile;)Ljava/security/cert/Certificate;
.method public static isSigned(Ljava/util/jar/JarFile;)Z
.method private static scanJar(Ljava/util/jar/JarFile;)V
在同一个 com/amazon/mas/kiwi/util 文件夹中还有一些类,例如 DeveloperInfo
(没那么有趣)、Base64
和 BC1
(用于校验和)。
在文件夹 com/amazon/android/ 中,您将找到 Kiwi
类
.class public final Lcom/amazon/android/Kiwi;
具有相当明显的领域:
.field private final drmFull:Z
该类 Kiwi 是应用程序中每个原始 smali 文件中的引用。示例:
.method public onCreate(Landroid/os/Bundle;)V
.locals 1
invoke-virtual p0, p1, Lxxx/xxxx/Xxxx;->xxxxXxxxx(Landroid/os/Bundle;)V
const/4 v0, 0x1
invoke-static p0, v0, Lcom/amazon/android/Kiwi;->onCreate(Landroid/app/Activity;Z)V
return-void
.end method
结论:
该方法涉及在 apk 的每个类中注入代码,可能通过反编译 apk、解析每个文件、添加必要的类以及使用相同的密钥重新编译。
【讨论】:
非常有趣!谢谢,在加拿大,我无法从 appstore 访问付费应用程序。所以我看到了调用 Kiwi 的代码。这不是很简单吗?通过从所有类中删除调用静态行? 这不是付费应用,我下载了一个免费的。他们可以为所有应用程序执行此操作,无论价格如何。 哦,真的。有趣,这应该对我有很大帮助。您对绕过 DRM 有多容易有什么看法?因为似乎只删除所有类上的那条线,drm 就没有用了。而不是谷歌的 DRM,它不是那么简单。 出于好奇,第一个invoke-virtual 是否指向onCreateApp?我一直在玩的一个 apk 就是这样。 好的,谢谢,看来亚马逊让应用程序的 onCreate 以另一种方法运行,然后通过该 kiwi 类在那里运行 DRM,并且由于它们传递了上下文,因此它们可以创建一个对话框来告诉用户如果它无效并停止应用程序继续前进。以上是关于将代码注入 APK的主要内容,如果未能解决你的问题,请参考以下文章
带你开发一款给Apk中自动注入代码工具icodetools(开凿篇)
带你开发一款给Apk中自己主动注入代码工具icodetools(开凿篇)
带你开发一款给Apk中自动注入代码工具icodetools(完善篇)