appdbg: A virtual machine disguised as a debugger
1. Objectives
Today’s apps are restless. The Java layer tries to flirt with the Native layer, and the Native layer likes to collude with Jave.
It’s too difficult to analyze a so quietly.
Is it possible to simulate the execution of the App on the PC, so that when Native is connected to the Jave layer, a lot of work of supplementing the environment can be saved?
appdbg is such a virtual machine disguised as a debugger.
https://github.com/asmjmp0/appdbg
The author’s introduction is:
make it possible to run android dex file in original Java Virtual Machine.
- change every class before it will be loaded
- change every item of the class after it was loaded
- hook java method
- implement native method by yourself or unidbg…
- provide java method level debug ability (dex2jar transformed class file without debug info,so we can’t step in)
Anyway, it looks pretty cool.
2. Steps
Install gradle first
My machine environment is as follows
- mac 10.14.6
- JDK 1.8
- IntelliJ idea 2020.1.2
The appdbg project is compiled with gradle, and idea can also configure it automatically, but it feels better to install gradle yourself.
brew install gradle
After the installation is complete, execute gradle -v to successfully print out the information, which means the installation is successful.
Start compiling — Configure sdk and ndk paths
First git clone the code, then run it in the root directorygradle build
* What went wrong:
A problem occurred configuring project ':test-app'.
> SDK location not found. Define location with an ANDROID_SDK_ROOT environment variable or by setting the sdk.dir path in your project's local properties file at '/Users/h1yx/Desktop/work/blogCode/ffgithub/appdbg/local.properties'.
As expected, an error message was reported. Since the author brought an Android App example, the compilation requires Android SDK and NDK. So you need to configure the paths of SDK and NDK first.
Add a file local.properties in the project root directory with the following content
sdk.dir=/Users/h1yx/Library/Android/sdk
The Android API in this project uses 31 compileSdkVersion 31 So I first downloaded Android Api 31 using the SDK Manager in Android Studio
Then configure the NDK path in test-app/build.gradle
android {
compileSdkVersion 31
buildToolsVersion "30.0.0"
ndkPath "/Users/h1yx/Library/Android/sdk/ndk/21.4.7075529"
...
}
Continue compiling
AndroidX control issues
/appdbg/test-app/src/main/java/jmp0/test/testapp/MainActivity.kt: (3, 24): Unresolved reference: v7
/appdbg/test-app/src/main/java/jmp0/test/testapp/MainActivity.kt: (11, 22): Unresolved reference: AppCompatActivity
This is a problem with Google’s UI upgrade. For Android programmers like us who are not very good at it, we can only ask Google.
// test-app/src/main/java/jmp0/test/testapp/MainActivity.kt
// import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
The next error is
/appdbg/test-app/src/main/java/jmp0/test/testapp/TestContext.kt: (9, 24): Unresolved reference: annotation
/appdbg/test-app/src/main/java/jmp0/test/testapp/TestContext.kt: (33, 6): Unresolved reference: RequiresApi
Google said that we should change it like this
// test-app/src/main/java/jmp0/test/testapp/TestContext.kt
// add h1yx
// import android.support.annotation.RequiresApi
import androidx.annotation.RequiresApi
Continue compiling
Android SDK version
Fix the issues identified by lint, or add the following to your build script to proceed with errors:
...
android {
lintOptions {
abortOnError false
}
}
...
Errors found:
/Users/zzx/Desktop/work/blogCode/ffgithub/appdbg/test-app/src/main/java/jmp0/test/testapp/TestContext.kt:55: Error: Call requires API level 26 (current min is 19): testIMEI [NewApi]
testIMEI()
~~~~~~~~
These are two errors. One seems to ask us to add a compilation command, and the other seems to think that our minSdkVersion is set too low.
Change it in test-app/build.gradle
android {
...
defaultConfig {
applicationId "jmp0.test.testapp"
minSdkVersion 28 // 19
。。。
}
...
lintOptions {
abortOnError false
}
...
}
The green BUILD SUCCESSFUL appears
run
Finally, it can run happily. The author said run main
I cried because I didn’t understand which main to run at first. There are quite a few mains in the project.
Later I found that it was probably run core/src/main/java/jmp0/Main.kt.
But there is no run after right clicking.
It’s so difficult to be a 20-year-old Java programmer.
I asked Google, and he said that in File → Project Structure, set core/src to sources.
1:setsrc
Now you can run the program by right clicking on the Main.kt file (if it still doesn’t appear, close IDEA and reopen it to wait for it to finish scanning indexing)
Don’t rush to run
There are two steps to do. The first step is to patch the JDK. This step is more troublesome.
I will just use the jdk prepared by the author
https://github.com/asmjmp0/appdbg-JDK
On Mac, you also need to re-sign libjvm.dylib. Find the signature id from the one registered in Xcode.
codesign -f -s "Developer ID Application: Fei Fen (HHZN32E11C)" libjvm.dylib
Another step is to patch rt.jar to support io redirection. This step only requires running the JDKmodify project. Use the generated rt.jar to replace the rt.jar in jdk
You’re done!
Let’s analyze the example in the main function.
Conclusion
During the compilation process, we also encountered
> Task :prepareKotlinBuildScriptModel UP-TO-DATE
IOException: https://dl.google.com/android/repository/addons_list-3.xml
java.net.ConnectException: Connection refused: connect
IOException: https://dl.google.com/android/repository/addons_list-2.xml
java.net.ConnectException: Connection refused: connect
IOException: https://dl.google.com/android/repository/addons_list-1.xml
java.net.ConnectException: Connection refused: connect
Failed to download any source lists!
This can be done with scientific Internet access.