JS `Jadx` / `Apktool` 对 Android `Hybrid App` 中的 JS 代码提取

各位老铁,早上好!今天咱们来聊聊安卓混合应用(Hybrid App)里那些“裸奔”的 JavaScript 代码,看看怎么用 Jadx 和 Apktool 把它们揪出来,让它们无处遁形。

引子:Hybrid App 的爱恨情仇

Hybrid App,顾名思义,就是“混血”App。它既有 Native App 的一些优点,比如可以访问设备硬件,又有 Web App 的跨平台能力。简单来说,就是用 WebView 控件加载 HTML、CSS 和 JavaScript 代码。

这种架构的优点很多,比如开发效率高、维护成本低、跨平台能力强。但是,它也有一个致命的缺点:JavaScript 代码容易被提取出来,存在一定的安全风险。

想象一下,如果你的 Hybrid App 里有一些核心的业务逻辑,比如支付算法、数据加密算法等,都被人轻轻松松地提取出来了,那岂不是要凉凉?

所以,保护 Hybrid App 里的 JavaScript 代码,是一个非常重要的课题。但是,在保护之前,我们首先得知道怎么把它提取出来,才能更好地进行防御。

第一部分:Apktool 的庖丁解牛

Apktool 是一个反编译 Android APK 文件的神器。它可以把 APK 文件解压成易于阅读的 smali 代码和资源文件。

1. Apktool 的安装与使用

首先,你需要下载 Apktool。官方网站是:https://ibotpeaches.github.io/Apktool/

下载完成后,按照官方文档进行安装。安装完成后,就可以使用 Apktool 来解压 APK 文件了。

apktool d your_app.apk

这条命令会将 your_app.apk 解压到一个名为 your_app 的文件夹里。

2. 寻找 JavaScript 的蛛丝马迹

解压完成后,我们需要在解压后的文件夹里寻找 JavaScript 代码的蛛丝马迹。

通常情况下,Hybrid App 的 JavaScript 代码会放在 assets 文件夹或者 www 文件夹里。

所以,我们可以先看看这两个文件夹里有没有 .js 文件或者 .html 文件。

ls your_app/assets
ls your_app/www

如果找到了 .js 文件或者 .html 文件,就可以用文本编辑器打开它们,看看里面有没有 JavaScript 代码。

3. WebView 的身影

除了直接放在 assets 或者 www 文件夹里,JavaScript 代码也可能通过 WebView 加载。

这时候,我们需要查看 AndroidManifest.xml 文件,找到使用了 WebView 的 Activity。

<activity
    android:name=".MainActivity"
    android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

找到 Activity 之后,我们需要查看 Activity 的 Java 代码,看看它是怎么加载 WebView 的。

通常情况下,Activity 的 Java 代码会放在 smali 文件夹里。

找到 Activity 的 smali 代码后,我们可以搜索 loadUrl 方法,看看它是怎么加载 JavaScript 代码的。

例如:

.line 25
iget-object v0, p0, Lcom/example/myapp/MainActivity;->webView:Landroid/webkit/WebView;

const-string v1, "file:///android_asset/www/index.html"

invoke-virtual {v0, v1}, Landroid/webkit/WebView;->loadUrl(Ljava/lang/String;)V

这段 smali 代码表示,MainActivity 中的 WebView 加载了 file:///android_asset/www/index.html 这个 URL。

通过这种方式,我们可以找到 WebView 加载的 JavaScript 代码。

第二部分:Jadx 的代码解剖

Jadx 是一个反编译 Android APK 文件的 Java 代码的反编译器。它可以将 APK 文件中的 DEX 文件反编译成 Java 代码。

1. Jadx 的安装与使用

首先,你需要下载 Jadx。官方网站是:https://github.com/skylot/jadx

下载完成后,按照官方文档进行安装。安装完成后,就可以使用 Jadx 来反编译 APK 文件了。

jadx your_app.apk

这条命令会将 your_app.apk 反编译成 Java 代码,并打开一个图形界面。

2. 寻找 JavaScript 的身影

在 Jadx 的图形界面里,我们可以像浏览 Java 代码一样,浏览 APK 文件中的 Java 代码。

我们需要找到使用了 WebView 的 Activity,然后查看 Activity 的 Java 代码,看看它是怎么加载 JavaScript 代码的。

例如:

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("file:///android_asset/www/index.html");
    }
}

这段 Java 代码表示,MainActivity 中的 WebView 加载了 file:///android_asset/www/index.html 这个 URL。

通过这种方式,我们可以找到 WebView 加载的 JavaScript 代码。

3. Java 调用 JavaScript

除了 WebView 加载 JavaScript 代码,Java 代码也可以直接调用 JavaScript 代码。

例如:

webView.evaluateJavascript("javascript:callFromJava('Hello from Java!')", null);

这段 Java 代码表示,Java 代码调用了 JavaScript 代码中的 callFromJava 方法,并传递了一个字符串参数 Hello from Java!

我们需要搜索 evaluateJavascript 方法,看看 Java 代码是怎么调用 JavaScript 代码的。

第三部分:实战演练

接下来,我们用一个简单的 Hybrid App 来演示一下如何提取 JavaScript 代码。

1. 创建一个简单的 Hybrid App

首先,我们创建一个简单的 Hybrid App。这个 App 只有一个 Activity,Activity 里有一个 WebView,WebView 加载一个 HTML 文件。

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/webView"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java:

package com.example.myapp;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.webkit.WebView;

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        webView = findViewById(R.id.webView);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("file:///android_asset/www/index.html");
    }
}

index.html:

<!DOCTYPE html>
<html>
<head>
    <title>My App</title>
</head>
<body>
    <h1>Hello from HTML!</h1>
    <script>
        function callFromJava(message) {
            alert(message);
        }
    </script>
</body>
</html>

index.html 文件放在 assets/www 目录下。

2. 使用 Apktool 解压 APK 文件

将 App 打包成 APK 文件后,使用 Apktool 解压 APK 文件。

apktool d app-debug.apk

3. 找到 JavaScript 代码

解压完成后,在 app-debug/assets/www 目录下可以找到 index.html 文件。打开 index.html 文件,就可以看到 JavaScript 代码了。

4. 使用 Jadx 反编译 APK 文件

使用 Jadx 反编译 APK 文件。

jadx app-debug.apk

5. 找到 Java 代码

反编译完成后,在 Jadx 的图形界面里,可以找到 MainActivity.java 文件。打开 MainActivity.java 文件,就可以看到 Java 代码了。

6. 总结

通过 Apktool 和 Jadx,我们可以轻松地提取 Hybrid App 里的 JavaScript 代码。

第四部分:JavaScript 代码保护策略

既然我们已经知道怎么提取 JavaScript 代码了,那么接下来就需要考虑如何保护 JavaScript 代码,防止被轻易提取。

以下是一些常用的 JavaScript 代码保护策略:

策略 优点 缺点
代码混淆 增加代码阅读难度,使攻击者难以理解代码逻辑 只能增加破解难度,不能完全防止破解
代码压缩 减小代码体积,加快加载速度 降低代码可读性,但对于专业的攻击者来说,作用有限
代码加密 对代码进行加密,只有运行时才能解密 增加了运行时的开销,可能影响性能
代码完整性校验 校验代码是否被篡改,如果被篡改则停止运行 需要额外的校验机制,增加了复杂度
WebView 安全设置 禁用 WebView 的一些不安全特性,比如文件访问、JavaScript 接口等 可能会影响 App 的功能
Native 代码封装核心逻辑 将核心逻辑放在 Native 代码里,增加破解难度 增加了开发和维护成本
动态加载 将部分 JavaScript 代码放在服务器上,运行时动态加载,增加攻击者获取完整代码的难度 需要网络连接,增加了复杂度和潜在的风险

1. 代码混淆

代码混淆是一种常用的 JavaScript 代码保护策略。它可以将代码中的变量名、函数名等替换成无意义的字符串,增加代码阅读难度。

常用的 JavaScript 代码混淆工具有:

  • UglifyJS
  • JavaScript Obfuscator
  • Closure Compiler

2. 代码压缩

代码压缩可以减小代码体积,加快加载速度。同时,它也可以降低代码可读性,增加破解难度。

常用的 JavaScript 代码压缩工具有:

  • UglifyJS
  • YUI Compressor
  • Google Closure Compiler

3. 代码加密

代码加密是一种更强的 JavaScript 代码保护策略。它可以将代码进行加密,只有运行时才能解密。

常用的 JavaScript 代码加密工具有:

  • JScrambler
  • DexGuard (Android 平台)

4. 代码完整性校验

代码完整性校验可以校验代码是否被篡改,如果被篡改则停止运行。

可以使用 MD5、SHA 等算法对代码进行校验。

5. WebView 安全设置

禁用 WebView 的一些不安全特性,比如文件访问、JavaScript 接口等。

6. Native 代码封装核心逻辑

将核心逻辑放在 Native 代码里,增加破解难度。

7. 动态加载

将部分 JavaScript 代码放在服务器上,运行时动态加载,增加攻击者获取完整代码的难度。

总结:攻防永无止境

今天我们学习了如何使用 Apktool 和 Jadx 提取 Hybrid App 里的 JavaScript 代码,以及一些常用的 JavaScript 代码保护策略。

需要注意的是,攻防永无止境。任何一种保护策略都不能完全防止破解。我们需要不断学习新的攻击技术和防御技术,才能更好地保护我们的 App。

希望今天的分享对大家有所帮助!下次再见!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注