从 Java 代码到 Android 执行

笔记转博文

还是以 Java hello world 为例,本文将展示从 Java -> class -> dex -> smali 的过程。
新建 com/dezng/Hello.java 文件。

package com.dezng;

public class Hello {
    public static void main(String[] args){
        System.out.println("Hello");
    }
}

1. Java -> class

使用 javac 编译得到 class 文件。执行看到输出 Hello

javac com/dezng/Hello.java
java com.dezng.Hello # Hello

2. class -> dex

class 到 dex 是通过 Android sdk 中提供的工具完成。位于 build-tools/{VERSION}/dx

这里需要注意的是不同版本 sdk 支持的 java 版本不一样,可能会出现 bad class file magic (cafebabe) or version (0034.0000)类似的错误,此错误信息是我用 23.0.1 转换 java 8 的字节码时出现的错误,26.0.0 以上版本可以使用 java 8,24和25没有安装,没有测试。

dx --dex --output=Hello.dex com/dezng/Hello.class
file Hello.dex # file 命令查看 dex 文件
# Hello.dex: Dalvik dex file version 035

在 Android sdk 中,和 dx 命令相同位置还存在一个 dexdump 的命令,可以用于查看 dex 中包含的内容,类似 javap。

dexdump Hello.dex
2.1 dex 文件的执行:

dex 文件是 Android 平台的可执行文件,可以在 Android 中直接执行。

adb push Hello.dex /data/local/tmp/
# Hello.dex: 1 file pushed, 0 skipped. 0.9 MB/s (832 bytes in 0.001s)

adb shell # 进入 Android 终端

cd /data/local/tmp
/data/local/tmp $ dalvikvm -cp Hello.dex com.dezng.Hello                                                                                                                                              
# Hello

3. dex -> smali

dex 文件的反编译,需要使用到 baksmali

java -jar baksmali.jar -o Hello.smali.out Hello.dex

之后在 Hello.smali.out 目录下可以看到文件 com/dezng/Hello.smali 文件。

.class public Lcom/dezng/Hello;
.super Ljava/lang/Object;
.source "Hello.java"


# annotations
.annotation runtime Ljava/lang/Deprecated;
.end annotation


# direct methods
.method public constructor <init>()V
    .registers 1

    .prologue
    .line 4
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static main([Ljava/lang/String;)V
    .registers 3

    .prologue
    .line 6
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    const-string v1, "Hello"

    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 7
    return-void
.end method

具体语法请参考 官方文档,想要系统学习,必看书籍Android软件安全与逆向分析

4. smali -> dex

将 smali 打包成 dex 需要用到 smali

java -jar smali.jar -o Hello.smali.dex Hello.smali.out

将以上 dex push 到手机,执行正常。

5. 参考链接

baksmali/smali
dalvik 字节码
Android软件安全与逆向分析

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当使用Java编写Android WorkManager代码时,你需要执行步骤: 1. 首先,在app模块的build.gradle文件中添加WorkManager的依赖项。在dependencies块中添加以下代码: ```groovy dependencies { def work_version = "2.7.0" implementation "androidx.work:work-runtime:$work_version" } ``` 2. 创建一个Worker类来执行后台任务。Worker类应继承自`androidx.work.Worker`类,并且需要实现`doWork()`方法。`doWork()`方法是在后台线程上运行的,你可以在其中执行耗时任务。 ```java import android.content.Context; import androidx.annotation.NonNull; import androidx.work.Worker; import androidx.work.WorkerParameters; public class MyWorker extends Worker { public MyWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) { super(context, workerParams); } @NonNull @Override public Result doWork() { // 执行后台任务逻辑 // 返回Result.success()表示任务执行成功,可以继续执行下一个任务 // 返回Result.failure()表示任务执行失败,WorkManager会根据重试策略进行重试 // 返回Result.retry()表示任务执行出现临时性错误,WorkManager会根据重试策略进行重试 return Result.success(); } } ``` 3. 使用WorkManager来调度和运行后台任务。下面是一个示例: ```java import androidx.work.Constraints; import androidx.work.NetworkType; import androidx.work.OneTimeWorkRequest; import androidx.work.WorkManager; Constraints constraints = new Constraints.Builder() .setRequiredNetworkType(NetworkType.UNMETERED) // 设置网络类型要求 .setRequiresCharging(true) // 设置要求在充电时运行 .build(); OneTimeWorkRequest workRequest = new OneTimeWorkRequest.Builder(MyWorker.class) .setConstraints(constraints) // 设置任务约束条件 .build(); WorkManager.getInstance(context).enqueue(workRequest); ``` 在上述示例中,我们创建了一个OneTimeWorkRequest,它表示只运行一次的后台任务。你可以根据需要选择不同的WorkRequest类型,例如PeriodicWorkRequest表示定期运行的后台任务。 这只是一个简单的示例,你还可以使用WorkManager的其他功能,如链式任务、任务重试策略等。你可以参考官方文档以获取更多详细信息:https://developer.android.com/topic/libraries/architecture/workmanager

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值