现在的App都不安分,Java层去和Native挤眉弄眼,Native层又喜欢和Jave去暗通款曲。
想安安静静的分析一个so太难了。
有没有可能把App在Pc上都模拟执行起来,这样Native再去勾搭Jave层的时候就可以节省很多补环境的工作了。
appdbg就是这样一个 伪装成调试器的虚拟机。
https://github.com/asmjmp0/appdbg
作者的介绍是:
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)
反正看上去很牛掰就是了。
我本机的环境如下
mac 10.14.6
jdk 1.8
intelliJ idea 2020.1.2
appdbg这个工程是用 gradle来编译的,idea也可以自动配置好,不过自己装个 gradle 感觉更好一点。
brew install gradle
安装完毕之后,执行 gradle -v 成功打印出信息就算安装成功了。
先把代码 git clone 下来,然后在根目录 运行 #gradle 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/fenfei/Desktop/work/blogCode/ffgithub/appdbg/local.properties'.
不出意外,报错了,由于作者带了一个Android App的例子,里面编译需要android sdk和ndk。所以要先配置下sdk和ndk的路径
在工程根目录下面增加一个文件 local.properties, 内容如下
# 针对自己电脑中的Android sdk路径来配置
sdk.dir=/Users/fenfei/Library/Android/sdk
这个工程里面 Android Api使用的是31 **compileSdkVersion 31 ** ,所以我先用 Android Studio中的 SDK Manager 下载了 Android Api 31
然后在 test-app/build.gradle 中配置一下这个NDK路径
android {
compileSdkVersion 31
buildToolsVersion "30.0.0"
ndkPath "/Users/fenfei/Library/Android/sdk/ndk/21.4.7075529"
...
}
继续编译
/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
这个是google的ui升级问题。 对于咱们这种二把刀Android程序员来说只能问谷哥了。
// test-app/src/main/java/jmp0/test/testapp/MainActivity.kt
// import android.support.v7.app.AppCompatActivity
import androidx.appcompat.app.AppCompatActivity
下一个错误是
/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
谷哥说了,要这么改
// test-app/src/main/java/jmp0/test/testapp/TestContext.kt
// add fenfei
// import android.support.annotation.RequiresApi
import androidx.annotation.RequiresApi
继续编译
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()
~~~~~~~~
这是两个错误,一个貌似是要让我们加上个编译命令, 另一个貌似是嫌咱们的 minSdkVersion 版本设置的太低。
在 test-app/build.gradle 中改改吧
android {
...
defaultConfig {
applicationId "jmp0.test.testapp"
minSdkVersion 28 // 19
。。。
}
...
lintOptions {
abortOnError false
}
...
}
绿色的 BUILD SUCCESSFUL 出现了
终于可以愉快的运行了。 作者说 run main
我哭了, 一开始 没搞明白 run 哪个 main。工程里面 main还不少呢。
后来发现 大概率是 run core/src/main/java/jmp0/Main.kt 这个main
但是 右键之后没有run呀。
二把刀java程序员太难了。
问了下谷哥,哥说了 File -> Project Structure 把 core/src 设置成 sources
这下在 Main.kt 文件上点右键 就可以run了 (如果还没出现,就把IDEA关闭之后重新打开下 等它 Scan indexing 结束)
先别着急run
有两步活要干,一步是给 jdk打补丁。 这一步比较麻烦
我就直接使用作者搞好的jdk
https://github.com/asmjmp0/appdbg-JDK
mac 下还需要把 libjvm.dylib 重新签一下名, 签名的id从 xcode里面之前注册好的找
codesign -f -s "Developer ID Application: Fei Fen (HHZN32E11C)" libjvm.dylib
另一步就是为了支持 io重定向,需要给 rt.jar打补丁。 这一步只需要运行JDKmodifiy工程就可以了。用生成的rt.jar 来替换jdk中的 rt.jar
可以好好分析一下 main函数中的例子了。
编译过程中还遇到了
> 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!
这个加上科学上网就可以了。
吃得苦中苦,才知道没有最苦,只有更苦。