connglli / blog-notes

My personal notes ✍️
MIT License
31 stars 2 forks source link

How to Write a System-Level Android (or Java) App (e.g. Monkey) #4

Open connglli opened 4 years ago

connglli commented 4 years ago

Introduction

Example

  1. Write a HelloWorld.java in directory src/com/example
  2. Compile to class in src: $ javac –cp /path/to/framework.jar com/example/HelloWorld.java
  3. Compile to jar: $ jar cvfe HelloWorld-jar.jar com.example.HelloWorld com/example/HelloWorld.class
  4. Compile to dex: $ d8 --output HelloWorld.dex HelloWorld-jar.jar
  5. Push to device: $ adb push HelloWorld.dex /data/local/tmp
  6. Run it in devices shell by either app_process or dalvikvm

    # app_process
    $ CLASSPATH=/data/local/tmp/HelloWorld.dex app_process /data/local/tmp com.example.HelloWorld
    
    # dalvikvm
    $ CLASSPATH=/data/local/tmp/HelloWorld.dex dalvikvm com.example.HelloWorld

see also #3

The Simplest Way

As long as a system-level app has no differences from a common app (except running in command line). The simplest way is no more easier than reusing the Android Studio tool chain.

  1. just create an Android project without any activities
  2. write your own codes, for example HelloWorld
  3. build the project like a normal project (AS would automatically compile them using javac and dx, and pack them into a classes.dex inside an apk)
  4. push the apk to the device
  5. use app_process/dalvikvm to run
    $ dalvikvm -cp /data/local/tmp/hello.apk com.example.HelloWorld

Debugging A System-Level App

JDWP provides the ability of debugging to JVM, which also works in dalvik/ART. Like CDP (chrome devtools protocol), JDWP defines a debugging protocol of any debugger frontend and the backend. So any client/server that implements the protocol can connect to each other.

Step1: Start debugging server

On devices with Android 8 and/or lower, JDWP is implemented using the java agent, i.e., the -agentlib option. To enable JDWP:

$ dalvikvm -cp /data/local/tmp/hello.apk -agentlib:jdwp=transport=dt_socket,suspend=y,server=y,address=5005 com.example.HelloWorld

Above options "transport=dt_socket,suspend=y,server=y,address=5005" tells JVM to enable JDWP as a TCP server at port 5005, and suspend the app once start.

On devices with Android 8+, use:

$ dalvikvm -cp /data/local/tmp/hello.apk -XjdwpProvider:internal -XjdwpOptions:transport=dt_socket,suspend=y,server=y,address=5005 com.example.HelloWorld

Step2: Forward the debugger

Forward that port to the desktop:

$ adb forward tcp:5005 tcp:5005

Step3: Set breakpoints and connect to the debugger

Set your breakpoints in Android Studio.

Then in the menu: Run > Debug > Edit configurations.... Click on + > Remote, and fill the following:

Then click Debug.

terukaze1939 commented 6 months ago

Hello, i try using ./android-sdk-linux/build-tools/30.0.3/d8 --output amogus.dex helloworld.jar

but an error occured, any idea? :(

Error: Invalid output: amogus.dex Output must be a .zip or .jar archive or an existing directory Compilation failed

Java information

openjdk 11.0.22 2024-01-16 OpenJDK Runtime Environment (build 11.0.22+7-post-Ubuntu-0ubuntu222.04.1) OpenJDK 64-Bit Server VM (build 11.0.22+7-post-Ubuntu-0ubuntu222.04.1, mixed mode, sharing)

Nevermind :D, i solved the issue change amogus.dex to name of the folder and the classes.dex will appear inside the folder